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

Paolo Bonzini pbonzini at redhat.com
Wed Nov 2 06:57:45 PDT 2011


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.

A more common name I've seen for this function is fullread or read_full 
(same for write).  For the version that just loops if EINTR, a more 
common name is saferead or read_safe.

> +    /* 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.

> +    while (write(fd, buf, size) != size) {

If write does a short write, you'll write the beginning of buf multiple 
times, or possibly end up with an infinite loop even.

> +        if (errno != EINTR) {
> +            return -1;
> +        }
> +    }

Paolo



More information about the Spice-devel mailing list