X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Ftcp.c;h=fda34a368d28ca34c3558b36f560c71e3a21ad38;hb=488eec10443c4a498a926fa4f57f74be892c461a;hp=c0999832d477baaac79eed02a0360ef5b624189a;hpb=f87b1b373a0df55080c1e6a5874f9a0a75c6fee8;p=ffmpeg diff --git a/libavformat/tcp.c b/libavformat/tcp.c index c0999832d47..fda34a368d2 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -24,6 +24,7 @@ #include "internal.h" #include "network.h" #include "os_support.h" +#include "url.h" #if HAVE_POLL_H #include #endif @@ -44,6 +45,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags) char buf[256]; int ret; socklen_t optlen; + int timeout = 100; char hostname[1024],proto[1024],path[1024]; char portstr[10]; @@ -56,6 +58,9 @@ static int tcp_open(URLContext *h, const char *uri, int flags) if (p) { if (av_find_info_tag(buf, sizeof(buf), "listen", p)) listen_socket = 1; + if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) { + timeout = strtol(buf, NULL, 10); + } } memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; @@ -63,7 +68,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags) snprintf(portstr, sizeof(portstr), "%d", port); ret = getaddrinfo(hostname, portstr, &hints, &ai); if (ret) { - av_log(NULL, AV_LOG_ERROR, + av_log(h, AV_LOG_ERROR, "Failed to resolve hostname %s: %s\n", hostname, gai_strerror(ret)); return AVERROR(EIO); @@ -72,6 +77,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags) cur_ai = ai; restart: + ret = AVERROR(EIO); fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol); if (fd < 0) goto fail; @@ -83,29 +89,30 @@ static int tcp_open(URLContext *h, const char *uri, int flags) fd1 = accept(fd, NULL, NULL); closesocket(fd); fd = fd1; + ff_socket_nonblock(fd, 1); } else { redo: + ff_socket_nonblock(fd, 1); ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen); } - ff_socket_nonblock(fd, 1); - if (ret < 0) { struct pollfd p = {fd, POLLOUT, 0}; - if (ff_neterrno() == AVERROR(EINTR)) { - if (url_interrupt_cb()) { + ret = ff_neterrno(); + if (ret == AVERROR(EINTR)) { + if (ff_check_interrupt(&h->interrupt_callback)) { ret = AVERROR_EXIT; goto fail1; } goto redo; } - if (ff_neterrno() != AVERROR(EINPROGRESS) && - ff_neterrno() != AVERROR(EAGAIN)) + if (ret != AVERROR(EINPROGRESS) && + ret != AVERROR(EAGAIN)) goto fail; /* wait until we are connected or until abort */ - for(;;) { - if (url_interrupt_cb()) { + while(timeout--) { + if (ff_check_interrupt(&h->interrupt_callback)) { ret = AVERROR_EXIT; goto fail1; } @@ -113,14 +120,18 @@ static int tcp_open(URLContext *h, const char *uri, int flags) if (ret > 0) break; } - + if (ret <= 0) { + ret = AVERROR(ETIMEDOUT); + goto fail; + } /* test error */ optlen = sizeof(ret); getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen); if (ret != 0) { - av_log(NULL, AV_LOG_ERROR, + av_log(h, AV_LOG_ERROR, "TCP connection to %s:%d failed: %s\n", hostname, port, strerror(ret)); + ret = AVERROR(ret); goto fail; } } @@ -143,7 +154,6 @@ static int tcp_open(URLContext *h, const char *uri, int flags) closesocket(fd); goto restart; } - ret = AVERROR(EIO); fail1: if (fd >= 0) closesocket(fd); @@ -194,11 +204,10 @@ static int tcp_get_file_handle(URLContext *h) } URLProtocol ff_tcp_protocol = { - "tcp", - tcp_open, - tcp_read, - tcp_write, - NULL, /* seek */ - tcp_close, + .name = "tcp", + .url_open = tcp_open, + .url_read = tcp_read, + .url_write = tcp_write, + .url_close = tcp_close, .url_get_file_handle = tcp_get_file_handle, };