On Sep13, 2011, at 13:07 , Florian Pflug wrote:
> Here's my suggested implementation for pg_write_nointr. pg_read_nointr should be similar
> (but obviously without the ENOSPC handling)
>
> <wrong pg_write_nointr implementation snipped>
Sorry for the self-reply. I realized only after hitting send that I
got the ENOSPC handling wrong again - we probably ought to check for
ENOSPC as well as ret == 0. Also, it seems preferable to return the
number of bytes actually written instead of -1 if we hit an error during
retry.
With this version, any return value other than <amount> signals an
error, the number of actually written bytes is reported even in the
case of an error (to the best of pg_write_nointr's knowledge), and
errno always indicates the kind of error.
int pg_write_nointr(int fd, const void *bytes, Size amount)
{int written = 0;
while (amount > 0){ int ret;
ret = write(fd, bytes, amount);
if ((ret < 0) && (errno == EINTR)) { /* interrupted by signal before first byte was written. Retry */
/* XXX: Is it safe to call CHECK_FOR_INTERRUPTS here? */ CHECK_FOR_INTERRUPTS();
continue; } else if (ret < 1) { /* error occurred. Abort */
if (ret == 0) /* out of disk space */ errno = ENOSPC;
if (written == 0) return -1; else return written; }
/* made progress */ written += ret; amount -= ret; bytes = (const char *) bytes + ret; /* XXX: Is it safe to
callCHECK_FOR_INTERRUPTS here? */ CHECK_FOR_INTERRUPTS();}
}
best regards,
Florian Pflug