[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