X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Ftcp.c;h=14b5e19cd960799bdb216adc15fd16d2756f8c26;hb=724b1f6a05dbbc75df70990469fe521b93a098de;hp=ffcc6ff13cc11faf6243afac2986d10eb8b8c37a;hpb=fdcdd5396e2214ecf9fa39cef03f46e5eba7170b;p=ffmpeg diff --git a/libavformat/tcp.c b/libavformat/tcp.c index ffcc6ff13cc..14b5e19cd96 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -20,6 +20,7 @@ */ #include "avformat.h" #include +#include "internal.h" #include "network.h" #include "os_support.h" #if HAVE_SYS_SELECT_H @@ -37,27 +38,29 @@ static int tcp_open(URLContext *h, const char *uri, int flags) struct addrinfo hints, *ai, *cur_ai; int port, fd = -1; TCPContext *s = NULL; - fd_set wfds; + fd_set wfds, efds; int fd_max, ret; struct timeval tv; socklen_t optlen; char hostname[1024],proto[1024],path[1024]; char portstr[10]; - if(!ff_network_init()) - return AVERROR(EIO); - - url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), + av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), uri); if (strcmp(proto,"tcp") || port <= 0 || port >= 65536) return AVERROR(EINVAL); memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; + hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; snprintf(portstr, sizeof(portstr), "%d", port); - if (getaddrinfo(hostname, portstr, &hints, &ai)) + ret = getaddrinfo(hostname, portstr, &hints, &ai); + if (ret) { + av_log(NULL, AV_LOG_ERROR, + "Failed to resolve hostname %s: %s\n", + hostname, gai_strerror(ret)); return AVERROR(EIO); + } cur_ai = ai; @@ -70,8 +73,11 @@ static int tcp_open(URLContext *h, const char *uri, int flags) redo: ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen); if (ret < 0) { - if (ff_neterrno() == FF_NETERROR(EINTR)) + if (ff_neterrno() == FF_NETERROR(EINTR)) { + if (url_interrupt_cb()) + goto fail1; goto redo; + } if (ff_neterrno() != FF_NETERROR(EINPROGRESS) && ff_neterrno() != FF_NETERROR(EAGAIN)) goto fail; @@ -84,19 +90,25 @@ static int tcp_open(URLContext *h, const char *uri, int flags) } fd_max = fd; FD_ZERO(&wfds); + FD_ZERO(&efds); FD_SET(fd, &wfds); + FD_SET(fd, &efds); tv.tv_sec = 0; tv.tv_usec = 100 * 1000; - ret = select(fd_max + 1, NULL, &wfds, NULL, &tv); - if (ret > 0 && FD_ISSET(fd, &wfds)) + ret = select(fd_max + 1, NULL, &wfds, &efds, &tv); + if (ret > 0 && (FD_ISSET(fd, &wfds) || FD_ISSET(fd, &efds))) break; } /* test error */ optlen = sizeof(ret); getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen); - if (ret != 0) + if (ret != 0) { + av_log(NULL, AV_LOG_ERROR, + "TCP connection to %s:%d failed: %s\n", + hostname, port, strerror(ret)); goto fail; + } } s = av_malloc(sizeof(TCPContext)); if (!s) { @@ -146,15 +158,17 @@ static int tcp_read(URLContext *h, uint8_t *buf, int size) if (len < 0) { if (ff_neterrno() != FF_NETERROR(EINTR) && ff_neterrno() != FF_NETERROR(EAGAIN)) - return AVERROR(ff_neterrno()); + return ff_neterrno(); } else return len; } else if (ret < 0) { + if (ff_neterrno() == FF_NETERROR(EINTR)) + continue; return -1; } } } -static int tcp_write(URLContext *h, uint8_t *buf, int size) +static int tcp_write(URLContext *h, const uint8_t *buf, int size) { TCPContext *s = h->priv_data; int ret, size1, fd_max, len; @@ -176,12 +190,14 @@ static int tcp_write(URLContext *h, uint8_t *buf, int size) if (len < 0) { if (ff_neterrno() != FF_NETERROR(EINTR) && ff_neterrno() != FF_NETERROR(EAGAIN)) - return AVERROR(ff_neterrno()); + return ff_neterrno(); continue; } size -= len; buf += len; } else if (ret < 0) { + if (ff_neterrno() == FF_NETERROR(EINTR)) + continue; return -1; } } @@ -192,7 +208,6 @@ static int tcp_close(URLContext *h) { TCPContext *s = h->priv_data; closesocket(s->fd); - ff_network_close(); av_free(s); return 0; }