mirror of https://git.ffmpeg.org/ffmpeg.git
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"
|
||||
#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__
|
||||
|
|
Loading…
Reference in New Issue