[FFmpeg-cvslog] network: factor out connect-listening code

Luca Barbato git at videolan.org
Sun Jun 2 11:18:48 CEST 2013


ffmpeg | branch: master | Luca Barbato <lu_zero at gentoo.org> | Fri May 31 03:05:13 2013 +0200| [f849a77e67959eb6a83eb59b784aeefdb98cb80a] | committer: Luca Barbato

network: factor out connect-listening code

Introduce ff_listen_connect, to be shared with the other
non-tcp network protocols.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f849a77e67959eb6a83eb59b784aeefdb98cb80a
---

 libavformat/network.c |   46 +++++++++++++++++++++++++++++++++++++++++++++
 libavformat/network.h |    5 ++++-
 libavformat/tcp.c     |   50 ++++++-------------------------------------------
 3 files changed, 56 insertions(+), 45 deletions(-)

diff --git a/libavformat/network.c b/libavformat/network.c
index 55d55af..6f43c41 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -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;
+}
diff --git a/libavformat/network.h b/libavformat/network.h
index db1b09a..454ea29 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -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 */
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index 6e4de0d..fff9e1f 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -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);



More information about the ffmpeg-cvslog mailing list