]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/tcp.c
lavfi: allow audio filters to request a given number of samples.
[ffmpeg] / libavformat / tcp.c
index e602a556d25c2c58663a507d60313138298d10ab..e77e4c5231e1118a1b352864c4854575050ce249 100644 (file)
@@ -28,7 +28,6 @@
 #if HAVE_POLL_H
 #include <poll.h>
 #endif
-#include <sys/time.h>
 
 typedef struct TCPContext {
     int fd;
@@ -37,9 +36,9 @@ typedef struct TCPContext {
 /* return non zero if error */
 static int tcp_open(URLContext *h, const char *uri, int flags)
 {
-    struct addrinfo hints, *ai, *cur_ai;
+    struct addrinfo hints = { 0 }, *ai, *cur_ai;
     int port, fd = -1;
-    TCPContext *s = NULL;
+    TCPContext *s = h->priv_data;
     int listen_socket = 0;
     const char *p;
     char buf[256];
@@ -62,7 +61,6 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
             timeout = strtol(buf, NULL, 10);
         }
     }
-    memset(&hints, 0, sizeof(hints));
     hints.ai_family = AF_UNSPEC;
     hints.ai_socktype = SOCK_STREAM;
     snprintf(portstr, sizeof(portstr), "%d", port);
@@ -84,9 +82,23 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
 
     if (listen_socket) {
         int fd1;
+        int reuse = 1;
+        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
         ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
-        listen(fd, 1);
+        if (ret) {
+            ret = ff_neterrno();
+            goto fail1;
+        }
+        ret = listen(fd, 1);
+        if (ret) {
+            ret = ff_neterrno();
+            goto fail1;
+        }
         fd1 = accept(fd, NULL, NULL);
+        if (fd1 < 0) {
+            ret = ff_neterrno();
+            goto fail1;
+        }
         closesocket(fd);
         fd = fd1;
         ff_socket_nonblock(fd, 1);
@@ -100,7 +112,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
         struct pollfd p = {fd, POLLOUT, 0};
         ret = ff_neterrno();
         if (ret == AVERROR(EINTR)) {
-            if (url_interrupt_cb()) {
+            if (ff_check_interrupt(&h->interrupt_callback)) {
                 ret = AVERROR_EXIT;
                 goto fail1;
             }
@@ -112,7 +124,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
 
         /* wait until we are connected or until abort */
         while(timeout--) {
-            if (url_interrupt_cb()) {
+            if (ff_check_interrupt(&h->interrupt_callback)) {
                 ret = AVERROR_EXIT;
                 goto fail1;
             }
@@ -126,21 +138,18 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
         }
         /* test error */
         optlen = sizeof(ret);
-        getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen);
+        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, strerror(ret));
-            ret = AVERROR(ret);
+                   hostname, port, errbuf);
             goto fail;
         }
     }
-    s = av_malloc(sizeof(TCPContext));
-    if (!s) {
-        freeaddrinfo(ai);
-        return AVERROR(ENOMEM);
-    }
-    h->priv_data = s;
     h->is_streamed = 1;
     s->fd = fd;
     freeaddrinfo(ai);
@@ -189,11 +198,26 @@ static int tcp_write(URLContext *h, const uint8_t *buf, int size)
     return ret < 0 ? ff_neterrno() : ret;
 }
 
+static int tcp_shutdown(URLContext *h, int flags)
+{
+    TCPContext *s = h->priv_data;
+    int how;
+
+    if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ) {
+        how = SHUT_RDWR;
+    } else if (flags & AVIO_FLAG_WRITE) {
+        how = SHUT_WR;
+    } else {
+        how = SHUT_RD;
+    }
+
+    return shutdown(s->fd, how);
+}
+
 static int tcp_close(URLContext *h)
 {
     TCPContext *s = h->priv_data;
     closesocket(s->fd);
-    av_free(s);
     return 0;
 }
 
@@ -210,4 +234,7 @@ URLProtocol ff_tcp_protocol = {
     .url_write           = tcp_write,
     .url_close           = tcp_close,
     .url_get_file_handle = tcp_get_file_handle,
+    .url_shutdown        = tcp_shutdown,
+    .priv_data_size      = sizeof(TCPContext),
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };