From 2cb98f7c62c63eedab93f2a0cc53383c5d8af9f0 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 2 Dec 2002 18:53:53 +0000 Subject: [PATCH] Synchronize safe-write with safe-read. --- lib/ChangeLog | 13 ++++++++++++ lib/safe-read.c | 17 ++++++++-------- lib/safe-write.c | 60 ++++++++++++++++++++++++++++++-------------------------- lib/safe-write.h | 6 ++++-- 4 files changed, 57 insertions(+), 39 deletions(-) diff --git a/lib/ChangeLog b/lib/ChangeLog index 6048d0687..21878382a 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,6 +1,19 @@ +2002-12-02 Bruno Haible + + * safe-write.c (CHAR_BIT, TYPE_SIGNED, TYPE_MINIMUM, TYPE_MAXIMUM): + Define, taken from safe-read.c. + (INT_MAX): Provide fallback. + (safe_write): Rewrite to iterate IFF the write fails with EINTR. + * safe-write.h (SAFE_WRITE_ERROR): Define. + + * safe-read.c (EINTR): Remove definition. + (safe_read): Don't use EINTR if it is absent. + 2002-12-02 Jim Meyering * safe-read.c (EINTR): Define. + (CHAR_BIT, TYPE_SIGNED, TYPE_MINIMUM, TYPE_MAXIMUM): Define. + (INT_MAX): Provide fallback. (safe_read): Rewrite to iterate IFF the read fails with EINTR. * safe-read.h (SAFE_READ_ERROR): Define. diff --git a/lib/safe-read.c b/lib/safe-read.c index 527653c5c..0d0f29ddd 100644 --- a/lib/safe-read.c +++ b/lib/safe-read.c @@ -57,12 +57,6 @@ extern int errno; Tru64 5.1. */ #define MAX_BYTES_TO_READ INT_MAX -#ifndef EINTR -/* If a system doesn't have support for EINTR, define it - to be a value to which errno will never be set. */ -# define EINTR (INT_MAX - 10) -#endif - /* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted. Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR upon error. */ @@ -72,9 +66,10 @@ safe_read (int fd, void *buf, size_t count) size_t nbytes_to_read = count; ssize_t result; - /* Limit the number of bytes to read, to avoid running - into unspecified behaviour. But keep the file pointer block - aligned when doing so. */ + /* Limit the number of bytes to read, to avoid running into unspecified + behaviour. But keep the file pointer block aligned when doing so. + Note that in this case we don't need to call read() multiple times here, + because the caller is prepared to partial results. */ if (nbytes_to_read > MAX_BYTES_TO_READ) nbytes_to_read = MAX_BYTES_TO_READ & ~8191; @@ -82,7 +77,11 @@ safe_read (int fd, void *buf, size_t count) { result = read (fd, buf, nbytes_to_read); } +#ifdef EINTR while (result < 0 && errno == EINTR); +#else + while (0); +#endif return (size_t) result; } diff --git a/lib/safe-write.c b/lib/safe-write.c index 55962039e..8c60bba39 100644 --- a/lib/safe-write.c +++ b/lib/safe-write.c @@ -35,6 +35,22 @@ extern int errno; #include +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif + +/* The extra casts work around common compiler bugs. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) +/* The outer cast is needed to work around a bug in Cray C 5.0.3.0. + It is necessary at least when t == time_t. */ +#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \ + ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) +#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t))) + +#ifndef INT_MAX +# define INT_MAX TYPE_MAXIMUM (int) +#endif + /* We don't pass an nbytes count > SSIZE_MAX to write() - POSIX says the effect would be implementation-defined. Also we don't pass an nbytes count > INT_MAX but <= SSIZE_MAX to write() - this triggers a bug in @@ -47,37 +63,25 @@ extern int errno; size_t safe_write (int fd, const void *buf, size_t count) { - size_t total_written = 0; + size_t nbytes_to_write = count; + ssize_t result; + + /* Limit the number of bytes to write, to avoid running into unspecified + behaviour. But keep the file pointer block aligned when doing so. + Note that in this case we don't need to call write() multiple times here, + because the caller is prepared to partial results. */ + if (nbytes_to_write > MAX_BYTES_TO_READ) + nbytes_to_write = MAX_BYTES_TO_READ & ~8191; - if (count > 0) + do { - const char *ptr = (const char *) buf; - do - { - size_t nbytes_to_write = count; - ssize_t result; - - /* Limit the number of bytes to write in one round, to avoid running - into unspecified behaviour. But keep the file pointer block - aligned when doing so. */ - if (nbytes_to_write > MAX_BYTES_TO_READ) - nbytes_to_write = MAX_BYTES_TO_READ & ~8191; - - result = write (fd, ptr, nbytes_to_write); - if (result < 0) - { + result = write (fd, buf, nbytes_to_write); + } #ifdef EINTR - if (errno == EINTR) - continue; + while (result < 0 && errno == EINTR); +#else + while (0); #endif - return result; - } - total_written += result; - ptr += result; - count -= result; - } - while (count > 0); - } - return total_written; + return (size_t) result; } diff --git a/lib/safe-write.h b/lib/safe-write.h index 25d1a4d48..ab1f45b4a 100644 --- a/lib/safe-write.h +++ b/lib/safe-write.h @@ -17,7 +17,9 @@ #include +#define SAFE_WRITE_ERROR ((size_t) -1) + /* Write up to COUNT bytes at BUF to descriptor FD, retrying if interrupted. - Return the actual number of bytes written, zero for EOF, or (size_t) -1 - for an error. */ + Return the actual number of bytes written, zero for EOF, or SAFE_WRITE_ERROR + upon error. */ extern size_t safe_write (int fd, const void *buf, size_t count); -- 2.11.0