From: Bruno Haible Date: Wed, 8 Jan 2003 18:45:37 +0000 (+0000) Subject: Update from current gnulib version. X-Git-Tag: v0.12~1185 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=efd08ccf75c50df6de39bcf06a489bafec81846c;p=thirdparty%2Fgettext.git Update from current gnulib version. --- diff --git a/lib/ChangeLog b/lib/ChangeLog index a4084aff7..931782918 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,12 @@ +2003-01-08 Bruno Haible + + * safe-read.h: Update from current gnulib version. + * safe-read.c: Update from current gnulib version. + * safe-write.h: Update from current gnulib version. + * safe-write.c: Update from current gnulib version. + * full-write.h: Update from current gnulib version. + * full-write.c: Update from current gnulib version. + 2002-12-16 Bruno Haible * copy-file.c: Include if doesn't exist. diff --git a/lib/full-write.c b/lib/full-write.c index f21e4791a..151370563 100644 --- a/lib/full-write.c +++ b/lib/full-write.c @@ -1,7 +1,6 @@ -/* An interface to write() that writes all it is asked to write. +/* An interface to read and write that retries (if necessary) until complete. - Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002 Free Software - Foundation, Inc. + Copyright (C) 1993, 1994, 1997-2003 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,45 +21,65 @@ #endif /* Specification. */ -#include "full-write.h" +#ifdef FULL_READ +# include "full-read.h" +#else +# include "full-write.h" +#endif #include #ifndef errno extern int errno; #endif -#include "safe-write.h" +#ifdef FULL_READ +# include "safe-read.h" +# define safe_rw safe_read +# define full_rw full_read +# undef const +# define const /* empty */ +#else +# include "safe-write.h" +# define safe_rw safe_write +# define full_rw full_write +#endif -/* Write COUNT bytes at BUF to descriptor FD, retrying if interrupted - or if partial writes occur. Return the number of bytes successfully - written, setting errno if that is less than COUNT. */ +#ifdef FULL_READ +/* Set errno to zero upon EOF. */ +# define ZERO_BYTE_TRANSFER_ERRNO 0 +#else +/* Some buggy drivers return 0 when one tries to write beyond + a device's end. (Example: Linux 1.2.13 on /dev/fd0.) + Set errno to ENOSPC so they get a sensible diagnostic. */ +# define ZERO_BYTE_TRANSFER_ERRNO ENOSPC +#endif + +/* Write(read) COUNT bytes at BUF to(from) descriptor FD, retrying if + interrupted or if a partial write(read) occurs. Return the number + of bytes transferred. + When writing, set errno if fewer than COUNT bytes are written. + When reading, if fewer than COUNT bytes are read, you must examine + errno to distinguish failure from EOF (errno == 0). */ size_t -full_write (int fd, const void *buf, size_t count) +full_rw (int fd, const void *buf, size_t count) { - size_t total_written = 0; + size_t total = 0; + const char *ptr = buf; - if (count > 0) + while (count > 0) { - const char *ptr = buf; - - do + size_t n_rw = safe_rw (fd, ptr, count); + if (n_rw == (size_t) -1) + break; + if (n_rw == 0) { - size_t written = safe_write (fd, ptr, count); - if (written == (size_t)-1) - break; - if (written == 0) - { - /* Some buggy drivers return 0 when you fall off a device's - end. (Example: Linux 1.2.13 on /dev/fd0.) */ - errno = ENOSPC; - break; - } - total_written += written; - ptr += written; - count -= written; + errno = ZERO_BYTE_TRANSFER_ERRNO; + break; } - while (count > 0); + total += n_rw; + ptr += n_rw; + count -= n_rw; } - return total_written; + return total; } diff --git a/lib/safe-read.c b/lib/safe-read.c index 79d85417d..c84c79b92 100644 --- a/lib/safe-read.c +++ b/lib/safe-read.c @@ -1,5 +1,5 @@ -/* An interface to read() that retries after interrupts. - Copyright (C) 1993, 1994, 1998, 2002 Free Software Foundation, Inc. +/* An interface to read and write that retries after interrupts. + Copyright (C) 1993, 1994, 1998, 2002-2003 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,7 +20,11 @@ #endif /* Specification. */ -#include "safe-read.h" +#ifdef SAFE_WRITE +# include "safe-write.h" +#else +# include "safe-read.h" +#endif /* Get ssize_t. */ #include @@ -33,51 +37,62 @@ extern int errno; #endif +#ifdef EINTR +# define IS_EINTR(x) ((x) == EINTR) +#else +# define IS_EINTR(x) 0 +#endif + #include -/* We don't pass an nbytes count > SSIZE_MAX to read() - POSIX says the - effect would be implementation-defined. Also we don't pass an nbytes - count > INT_MAX but <= SSIZE_MAX to read() - this triggers a bug in - Tru64 5.1. */ -#define MAX_BYTES_TO_READ INT_MAX +#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))) -/* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted. - Return the actual number of bytes read, zero for EOF, or (size_t) -1 - for an error. */ +#ifndef INT_MAX +# define INT_MAX TYPE_MAXIMUM (int) +#endif + +#ifdef SAFE_WRITE +# define safe_rw safe_write +# define rw write +#else +# define safe_rw safe_read +# define rw read +# undef const +# define const /* empty */ +#endif + +/* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if + interrupted. Return the actual number of bytes read(written), zero for EOF, + or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error. */ size_t -safe_read (int fd, void *buf, size_t count) +safe_rw (int fd, void const *buf, size_t count) { - size_t total_read = 0; + ssize_t result; - if (count > 0) + /* POSIX limits COUNT to SSIZE_MAX, but we limit it further, requiring + that COUNT <= INT_MAX, to avoid triggering a bug in Tru64 5.1. + When decreasing COUNT, keep the file pointer block-aligned. + Note that in any case, read(write) may succeed, yet read(write) + fewer than COUNT bytes, so the caller must be prepared to handle + partial results. */ + if (count > INT_MAX) + count = INT_MAX & ~8191; + + do { - char *ptr = (char *) buf; - do - { - size_t nbytes_to_read = count; - ssize_t result; - - /* Limit the number of bytes to read in one round, to avoid running - into unspecified behaviour. But keep the file pointer block - aligned when doing so. */ - if (nbytes_to_read > MAX_BYTES_TO_READ) - nbytes_to_read = MAX_BYTES_TO_READ & ~8191; - - result = read (fd, ptr, nbytes_to_read); - if (result < 0) - { -#ifdef EINTR - if (errno == EINTR) - continue; -#endif - return result; - } - total_read += result; - ptr += result; - count -= result; - } - while (count > 0); + result = rw (fd, buf, count); } + while (result < 0 && IS_EINTR (errno)); - return total_read; + return (size_t) result; } diff --git a/lib/safe-read.h b/lib/safe-read.h index c4445ac1b..cbe6e0bfd 100644 --- a/lib/safe-read.h +++ b/lib/safe-read.h @@ -17,7 +17,9 @@ #include +#define SAFE_READ_ERROR ((size_t) -1) + /* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted. - Return the actual number of bytes read, zero for EOF, or (size_t) -1 - for an error. */ + Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR + upon error. */ extern size_t safe_read (int fd, void *buf, size_t count); diff --git a/lib/safe-write.c b/lib/safe-write.c index 55962039e..fbafa7cc6 100644 --- a/lib/safe-write.c +++ b/lib/safe-write.c @@ -1,5 +1,5 @@ -/* An interface to write() that retries after interrupts. - Copyright (C) 1993, 1994, 1998, 2002 Free Software Foundation, Inc. +/* An interface to write that retries after interrupts. + Copyright (C) 2002 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,69 +15,5 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#if HAVE_CONFIG_H -# include -#endif - -/* Specification. */ -#include "safe-write.h" - -/* Get ssize_t. */ -#include -#if HAVE_UNISTD_H -# include -#endif - -#include -#ifndef errno -extern int errno; -#endif - -#include - -/* 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 - Tru64 5.1. */ -#define MAX_BYTES_TO_READ INT_MAX - -/* 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. */ -size_t -safe_write (int fd, const void *buf, size_t count) -{ - size_t total_written = 0; - - if (count > 0) - { - 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) - { -#ifdef EINTR - if (errno == EINTR) - continue; -#endif - return result; - } - total_written += result; - ptr += result; - count -= result; - } - while (count > 0); - } - - return total_written; -} +#define SAFE_WRITE +#include "safe-read.c" 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);