mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-08 13:22:53 +02:00
support aborting in TCP
Originally committed as revision 2061 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
b7b8fc3406
commit
09787fb8af
@ -28,6 +28,8 @@
|
|||||||
# include "barpainet.h"
|
# include "barpainet.h"
|
||||||
#endif
|
#endif
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
typedef struct TCPContext {
|
typedef struct TCPContext {
|
||||||
int fd;
|
int fd;
|
||||||
@ -55,7 +57,11 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
|
|||||||
int port, fd = -1;
|
int port, fd = -1;
|
||||||
TCPContext *s;
|
TCPContext *s;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
fd_set wfds;
|
||||||
|
int fd_max, ret;
|
||||||
|
struct timeval tv;
|
||||||
|
socklen_t optlen;
|
||||||
|
|
||||||
s = av_malloc(sizeof(TCPContext));
|
s = av_malloc(sizeof(TCPContext));
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -85,32 +91,72 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
|
|||||||
fd = socket(PF_INET, SOCK_STREAM, 0);
|
fd = socket(PF_INET, SOCK_STREAM, 0);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||||
|
|
||||||
|
redo:
|
||||||
|
ret = connect(fd, (struct sockaddr *)&dest_addr,
|
||||||
|
sizeof(dest_addr));
|
||||||
|
if (ret < 0) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
goto redo;
|
||||||
|
if (errno != EINPROGRESS)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
if (connect(fd, (struct sockaddr *)&dest_addr,
|
/* wait until we are connected or until abort */
|
||||||
sizeof(dest_addr)) < 0)
|
for(;;) {
|
||||||
goto fail;
|
if (url_interrupt_cb()) {
|
||||||
|
ret = -EINTR;
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
fd_max = fd;
|
||||||
|
FD_ZERO(&wfds);
|
||||||
|
FD_SET(fd, &wfds);
|
||||||
|
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))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* test error */
|
||||||
|
optlen = sizeof(ret);
|
||||||
|
getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen);
|
||||||
|
if (ret != 0)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
s->fd = fd;
|
s->fd = fd;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
ret = -EIO;
|
||||||
|
fail1:
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
close(fd);
|
close(fd);
|
||||||
av_free(s);
|
av_free(s);
|
||||||
return -EIO;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tcp_read(URLContext *h, uint8_t *buf, int size)
|
static int tcp_read(URLContext *h, uint8_t *buf, int size)
|
||||||
{
|
{
|
||||||
TCPContext *s = h->priv_data;
|
TCPContext *s = h->priv_data;
|
||||||
int size1, len;
|
int size1, len, fd_max;
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
size1 = size;
|
size1 = size;
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
#ifdef CONFIG_BEOS_NETSERVER
|
if (url_interrupt_cb())
|
||||||
len = recv (s->fd, buf, size, 0);
|
return -EINTR;
|
||||||
|
fd_max = s->fd;
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(s->fd, &rfds);
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 100 * 1000;
|
||||||
|
select(fd_max + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
#ifdef __BEOS__
|
||||||
|
len = recv(s->fd, buf, size, 0);
|
||||||
#else
|
#else
|
||||||
len = read (s->fd, buf, size);
|
len = read(s->fd, buf, size);
|
||||||
#endif
|
#endif
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
if (errno != EINTR && errno != EAGAIN)
|
if (errno != EINTR && errno != EAGAIN)
|
||||||
@ -133,14 +179,24 @@ static int tcp_read(URLContext *h, uint8_t *buf, int size)
|
|||||||
static int tcp_write(URLContext *h, uint8_t *buf, int size)
|
static int tcp_write(URLContext *h, uint8_t *buf, int size)
|
||||||
{
|
{
|
||||||
TCPContext *s = h->priv_data;
|
TCPContext *s = h->priv_data;
|
||||||
int ret, size1;
|
int ret, size1, fd_max;
|
||||||
|
fd_set wfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
size1 = size;
|
size1 = size;
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
#ifdef CONFIG_BEOS_NETSERVER
|
if (url_interrupt_cb())
|
||||||
ret = send (s->fd, buf, size, 0);
|
return -EINTR;
|
||||||
|
fd_max = s->fd;
|
||||||
|
FD_ZERO(&wfds);
|
||||||
|
FD_SET(s->fd, &wfds);
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 100 * 1000;
|
||||||
|
select(fd_max + 1, NULL, &wfds, NULL, &tv);
|
||||||
|
#ifdef __BEOS__
|
||||||
|
ret = send(s->fd, buf, size, 0);
|
||||||
#else
|
#else
|
||||||
ret = write (s->fd, buf, size);
|
ret = write(s->fd, buf, size);
|
||||||
#endif
|
#endif
|
||||||
if (ret < 0 && errno != EINTR && errno != EAGAIN)
|
if (ret < 0 && errno != EINTR && errno != EAGAIN)
|
||||||
#ifdef __BEOS__
|
#ifdef __BEOS__
|
||||||
|
Loading…
Reference in New Issue
Block a user