support aborting in TCP

Originally committed as revision 2061 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Fabrice Bellard 2003-07-17 10:28:27 +00:00
parent b7b8fc3406
commit 09787fb8af
1 changed files with 70 additions and 14 deletions

View File

@ -28,6 +28,8 @@
# include "barpainet.h"
#endif
#include <netdb.h>
#include <sys/time.h>
#include <fcntl.h>
typedef struct TCPContext {
int fd;
@ -55,7 +57,11 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
int port, fd = -1;
TCPContext *s;
const char *p;
fd_set wfds;
int fd_max, ret;
struct timeval tv;
socklen_t optlen;
s = av_malloc(sizeof(TCPContext));
if (!s)
return -ENOMEM;
@ -85,32 +91,72 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
fd = socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0)
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,
sizeof(dest_addr)) < 0)
goto fail;
/* wait until we are connected or until abort */
for(;;) {
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;
return 0;
fail:
ret = -EIO;
fail1:
if (fd >= 0)
close(fd);
av_free(s);
return -EIO;
return ret;
}
static int tcp_read(URLContext *h, uint8_t *buf, int size)
{
TCPContext *s = h->priv_data;
int size1, len;
int size1, len, fd_max;
fd_set rfds;
struct timeval tv;
size1 = size;
while (size > 0) {
#ifdef CONFIG_BEOS_NETSERVER
len = recv (s->fd, buf, size, 0);
if (url_interrupt_cb())
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
len = read (s->fd, buf, size);
len = read(s->fd, buf, size);
#endif
if (len < 0) {
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)
{
TCPContext *s = h->priv_data;
int ret, size1;
int ret, size1, fd_max;
fd_set wfds;
struct timeval tv;
size1 = size;
while (size > 0) {
#ifdef CONFIG_BEOS_NETSERVER
ret = send (s->fd, buf, size, 0);
if (url_interrupt_cb())
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
ret = write (s->fd, buf, size);
ret = write(s->fd, buf, size);
#endif
if (ret < 0 && errno != EINTR && errno != EAGAIN)
#ifdef __BEOS__