New submission from Max <shakhmetov....@gmail.com>:

1. functions tcp_read and tcp_write is performing analyze  of 
URLContext::flags is URL_FLAG_NONBLOCK setted or not. But 
URL_FLAG_NONBLOCK is never set. Seems that in function tcp_open it must 
be set.
2. function tcp_read must have cycle for read all data. Now the function 
wait noly 100ms for incoming data. It's wrong. Seems that it must be 
like udp_read. 
3. function tcp_write must have cycle for read all data. Now the 
function wait noly 100ms for incoming data. It's wrong. Seems that it 
must be like udp_write.

For example:


static int tcp_read(URLContext *h, uint8_t *buf, int size)
{
    TCPContext *s = h->priv_data;
    struct pollfd p = {s->fd, POLLIN, 0};
    int len = 0;
    int ret;

        if ( 0 != (h->flags & URL_FLAG_NONBLOCK) ) {
                for ( ; 0 < size ; ) {
                        if ( url_interrupt_cb() )
                                return AVERROR(EINTR);
                        ret = poll(&p, 1, 100);
                        if (ret < 0) {
                                if ( ff_neterrno() == FF_NETERROR(EINTR) 
)
                                        continue;
                                return AVERROR(EIO);
                        }
                        if ( !(ret == 1 && p.revents & POLLIN) )
                                continue;
                        ret = recv(s->fd, buf, size, 0);
                        if (ret < 0) {
                                if (ff_neterrno() != FF_NETERROR(EAGAIN) 
&&
                                        ff_neterrno() != 
FF_NETERROR(EINTR))
                                        return AVERROR(EIO);
                        } else {
                                size -= ret;
                                buf += ret;
                                len += ret;
                        }
                }
        } else {
                len = recv(s->fd, buf, size, 0);
        }
    return len;
}

/******************************************************/

static int tcp_write(URLContext *h, const uint8_t *buf, int size)
{
    TCPContext *s = h->priv_data;
    struct pollfd p = {s->fd, POLLOUT, 0};
    int len = 0;
    int ret;

        if ( 0 != (h->flags & URL_FLAG_NONBLOCK) ) {
                for ( ; 0 < size ; ) {
                        if ( url_interrupt_cb() )
                                return AVERROR(EINTR);
                        ret = poll(&p, 1, 100);
                        if (ret < 0) {
                                if ( ff_neterrno() == FF_NETERROR(EINTR) 
)
                                        continue;
                                return AVERROR(EIO);
                        }
                        if ( !(ret == 1 && p.revents & POLLOUT) )
                                continue;
                        ret = send(s->fd, buf, size, 0);
                        if (ret < 0) {
                                if (ff_neterrno() != FF_NETERROR(EAGAIN) 
&&
                                        ff_neterrno() != 
FF_NETERROR(EINTR))
                                        return AVERROR(EIO);
                        } else {
                                size -= ret;
                                buf += ret;
                                len += ret;
                        }
                }
        } else {
                len = send(s->fd, buf, size, 0);
        }
    return len;
}
static int tcp_write(URLContext *h, const uint8_t *buf, int size)
{
    TCPContext *s = h->priv_data;
    struct pollfd p = {s->fd, POLLOUT, 0};
    int len = 0;
    int ret;

        if ( 0 != (h->flags & URL_FLAG_NONBLOCK) ) {
                for ( ; 0 < size ; ) {
                        if ( url_interrupt_cb() )
                                return AVERROR(EINTR);
                        ret = poll(&p, 1, 100);
                        if (ret < 0) {
                                if ( ff_neterrno() == FF_NETERROR(EINTR) 
)
                                        continue;
                                return AVERROR(EIO);
                        }
                        if ( !(ret == 1 && p.revents & POLLOUT) )
                                continue;
                        ret = send(s->fd, buf, size, 0);
                        if (ret < 0) {
                                if (ff_neterrno() != FF_NETERROR(EAGAIN) 
&&
                                        ff_neterrno() != 
FF_NETERROR(EINTR))
                                        return AVERROR(EIO);
                        } else {
                                size -= ret;
                                buf += ret;
                                len += ret;
                        }
                }
        } else {
                len = send(s->fd, buf, size, 0);
        }
    return len;
}

----------
messages: 13682
priority: normal
status: new
substatus: new
title: bug in libavcodec/tcp.c
type: bug

________________________________________________
FFmpeg issue tracker <iss...@roundup.ffmpeg.org>
<https://roundup.ffmpeg.org/issue2611>
________________________________________________

Reply via email to