summaryrefslogtreecommitdiff
path: root/libavformat/tcp.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-04-08 02:50:13 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-04-08 02:50:13 +0200
commitc88caa522c41cd4108d39d8dd98805e867606ae3 (patch)
tree90eacfa0065bb907cd6543f5b2865d31d3d0a677 /libavformat/tcp.c
parentdb95e559f2b1c392295b09e8457d6f161eb5acdb (diff)
parenta2031251c7eedd0d82cb9e08717990fa2ae6299f (diff)
Merge remote branch 'qatar/master'
* qatar/master: proto: include os_support.h in network.h matroskaenc: don't write an empty Cues element. lavc: add a FF_API_REQUEST_CHANNELS deprecation macro avio: move extern url_interrupt_cb declaration from avio.h to url.h avio: make av_register_protocol2 internal. avio: avio_ prefix for url_set_interrupt_cb. avio: AVIO_ prefixes for URL_ open flags. proto: introduce listen option in tcp doc: clarify configure features proto: factor ff_network_wait_fd and use it on udp Conflicts: ffmpeg.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/tcp.c')
-rw-r--r--libavformat/tcp.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index fb94b63984..f0d1c4556f 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -19,10 +19,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
+#include "libavutil/parseutils.h"
#include <unistd.h>
#include "internal.h"
#include "network.h"
#include "os_support.h"
+#include "url.h"
#if HAVE_POLL_H
#include <poll.h>
#endif
@@ -38,6 +40,9 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
struct addrinfo hints, *ai, *cur_ai;
int port, fd = -1;
TCPContext *s = NULL;
+ int listen_socket = 0;
+ const char *p;
+ char buf[256];
int ret;
socklen_t optlen;
char hostname[1024],proto[1024],path[1024];
@@ -48,6 +53,11 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
if (strcmp(proto,"tcp") || port <= 0 || port >= 65536)
return AVERROR(EINVAL);
+ p = strchr(uri, '?');
+ if (p) {
+ if (av_find_info_tag(buf, sizeof(buf), "listen", p))
+ listen_socket = 1;
+ }
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
@@ -66,10 +76,21 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
if (fd < 0)
goto fail;
- ff_socket_nonblock(fd, 1);
+ if (listen_socket) {
+ int fd1;
+ ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
+ listen(fd, 1);
+ fd1 = accept(fd, NULL, NULL);
+ closesocket(fd);
+ fd = fd1;
+ } else {
redo:
- ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
+ ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
+ }
+
+ ff_socket_nonblock(fd, 1);
+
if (ret < 0) {
int timeout=50;
struct pollfd p = {fd, POLLOUT, 0};
@@ -138,23 +159,13 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
return ret;
}
-static int tcp_wait_fd(int fd, int write)
-{
- int ev = write ? POLLOUT : POLLIN;
- struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
- int ret;
-
- ret = poll(&p, 1, 100);
- return ret < 0 ? ff_neterrno() : p.revents & ev ? 0 : AVERROR(EAGAIN);
-}
-
static int tcp_read(URLContext *h, uint8_t *buf, int size)
{
TCPContext *s = h->priv_data;
int ret;
- if (!(h->flags & URL_FLAG_NONBLOCK)) {
- ret = tcp_wait_fd(s->fd, 0);
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = ff_network_wait_fd(s->fd, 0);
if (ret < 0)
return ret;
}
@@ -167,8 +178,8 @@ static int tcp_write(URLContext *h, const uint8_t *buf, int size)
TCPContext *s = h->priv_data;
int ret;
- if (!(h->flags & URL_FLAG_NONBLOCK)) {
- ret = tcp_wait_fd(s->fd, 1);
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = ff_network_wait_fd(s->fd, 1);
if (ret < 0)
return ret;
}