* 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
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];
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;
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};
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;
}
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;
}
}
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,
};