[Spice-devel] [RFC 2/3] server: introduce dispatcher

Paolo Bonzini pbonzini at redhat.com
Wed Nov 2 08:08:05 PDT 2011


On 11/02/2011 04:05 PM, Alon Levy wrote:
> On Wed, Nov 02, 2011 at 02:57:45PM +0100, Paolo Bonzini wrote:
>> On 11/01/2011 09:10 AM, Alon Levy wrote:
>>> +/*
>>> + * read_with_eintr
>>> + * helper. reads until size bytes accumulated in buf, if an error other then
>>> + * EINTR is encountered returns -1, otherwise returns 0.
>>> + */
>>> +int read_with_eintr(int fd, void *buf, size_t size)
>>> +{
>>> +    int read_size = 0;
>>> +    int ret;
>>> +
>>> +    while (read_size<   size) {
>>> +        ret = read(fd, buf + read_size, size - read_size);
>>> +        if (ret == -1) {
>>> +            if (errno != EINTR) {
>>> +                return -1;
>>> +            }
>>> +            continue;
>>> +        }
>>> +        read_size += size;
>>> +    }
>>> +    return 0;
>>> +}
>>
>> This fails if read returns zero.  It can do so for a broken pipe on
>> the read side, even if fd is blocking.
>
> I mean to treat a broken pipe as a grave error.

I don't think an infinite loop is what you want though. :)  Reading from 
a broken pipe returns 0, not SIGPIPE or EPIPE.

>>> +    /* according to the man page EINTR will mean no data written, so
>>> +     * no need to take account of short writes. */
>>
>> write can certainly do short writes if fd's buffer is too small for
>> "buf"!  It can also return zero if fd is in non-blocking mode, but
>> I'm not sure that this is a problem for you.
>
> Per Yonit's comments I'm going to change the socketpair to non blocking,
> so I'll update the function to handle short writes.

FWIW, you can get short writes (though not zero-writes) even for 
blocking sockets.

Paolo


More information about the Spice-devel mailing list