]> git.sesse.net Git - ffmpeg/commitdiff
network: factor out connect-listening code
authorLuca Barbato <lu_zero@gentoo.org>
Fri, 31 May 2013 01:05:13 +0000 (03:05 +0200)
committerLuca Barbato <lu_zero@gentoo.org>
Sat, 1 Jun 2013 13:29:53 +0000 (15:29 +0200)
Introduce ff_listen_connect, to be shared with the other
non-tcp network protocols.

libavformat/network.c
libavformat/network.h
libavformat/tcp.c

index 55d55af35dfb08014a1a8c69caeb23de79cad4c5..6f43c416266497528eb8922a5610b48bca4a3009 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "network.h"
+#include "url.h"
 #include "libavcodec/internal.h"
 #include "libavutil/mem.h"
 
@@ -216,3 +217,48 @@ int ff_listen_bind(int fd, const struct sockaddr *addr,
     ff_socket_nonblock(ret, 1);
     return ret;
 }
+
+int ff_listen_connect(int fd, const struct sockaddr *addr,
+                      socklen_t addrlen, int timeout, URLContext *h)
+{
+    struct pollfd p = {fd, POLLOUT, 0};
+    int ret;
+    socklen_t optlen;
+
+    ff_socket_nonblock(fd, 1);
+
+    while ((ret = connect(fd, addr, addrlen))) {
+        ret = ff_neterrno();
+        switch (ret) {
+        case AVERROR(EINTR):
+            if (ff_check_interrupt(&h->interrupt_callback))
+                return AVERROR_EXIT;
+            continue;
+        case AVERROR(EINPROGRESS):
+        case AVERROR(EAGAIN):
+            while (timeout--) {
+                if (ff_check_interrupt(&h->interrupt_callback))
+                    return AVERROR_EXIT;
+                ret = poll(&p, 1, 100);
+                if (ret > 0)
+                    break;
+            }
+            if (ret <= 0)
+                return AVERROR(ETIMEDOUT);
+            optlen = sizeof(ret);
+            if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
+                ret = AVUNERROR(ff_neterrno());
+            if (ret != 0) {
+                char errbuf[100];
+                ret = AVERROR(ret);
+                av_strerror(ret, errbuf, sizeof(errbuf));
+                av_log(h, AV_LOG_ERROR,
+                       "Connection to %s failed: %s\n",
+                       h->filename, errbuf);
+            }
+        default:
+            return ret;
+        }
+    }
+    return ret;
+}
index db1b09a91ee602a5512a57fa41b2d548a63d326e..454ea292521823382f74d86502da359bbeccd5eb 100644 (file)
@@ -27,6 +27,7 @@
 #include "config.h"
 #include "libavutil/error.h"
 #include "os_support.h"
+#include "url.h"
 
 #if HAVE_UNISTD_H
 #include <unistd.h>
@@ -211,5 +212,7 @@ int ff_is_multicast_address(struct sockaddr *addr);
 
 int ff_listen_bind(int fd, const struct sockaddr *addr,
                    socklen_t addrlen, int timeout);
-
+int ff_listen_connect(int fd, const struct sockaddr *addr,
+                      socklen_t addrlen, int timeout,
+                      URLContext *h);
 #endif /* AVFORMAT_NETWORK_H */
index 6e4de0db6b5099fb9454ae50048cd87d29f722ed..fff9e1fcd40f4956db1936a1cee1ce708df9effe 100644 (file)
@@ -42,7 +42,6 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
     const char *p;
     char buf[256];
     int ret;
-    socklen_t optlen;
     int timeout = 100, listen_timeout = -1;
     char hostname[1024],proto[1024],path[1024];
     char portstr[10];
@@ -98,53 +97,16 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
             goto fail1;
         }
     } else {
- redo:
-        ff_socket_nonblock(fd, 1);
-        ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
-    }
+        if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
+                                     timeout, h)) < 0) {
 
-    if (ret < 0) {
-        struct pollfd p = {fd, POLLOUT, 0};
-        ret = ff_neterrno();
-        if (ret == AVERROR(EINTR)) {
-            if (ff_check_interrupt(&h->interrupt_callback)) {
-                ret = AVERROR_EXIT;
-                goto fail1;
-            }
-            goto redo;
-        }
-        if (ret != AVERROR(EINPROGRESS) &&
-            ret != AVERROR(EAGAIN))
-            goto fail;
-
-        /* wait until we are connected or until abort */
-        while(timeout--) {
-            if (ff_check_interrupt(&h->interrupt_callback)) {
-                ret = AVERROR_EXIT;
+            if (ret == AVERROR_EXIT)
                 goto fail1;
-            }
-            ret = poll(&p, 1, 100);
-            if (ret > 0)
-                break;
-        }
-        if (ret <= 0) {
-            ret = AVERROR(ETIMEDOUT);
-            goto fail;
-        }
-        /* test error */
-        optlen = sizeof(ret);
-        if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
-            ret = AVUNERROR(ff_neterrno());
-        if (ret != 0) {
-            char errbuf[100];
-            ret = AVERROR(ret);
-            av_strerror(ret, errbuf, sizeof(errbuf));
-            av_log(h, AV_LOG_ERROR,
-                   "TCP connection to %s:%d failed: %s\n",
-                   hostname, port, errbuf);
-            goto fail;
+            else
+                goto fail;
         }
     }
+
     h->is_streamed = 1;
     s->fd = fd;
     freeaddrinfo(ai);