From 4c6c221ee2b48595f812e58780097f79ca18506f Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sun, 1 Dec 2002 11:53:02 +0000 Subject: Merge from gnulib. --- lib/safe-read.c | 71 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 31 deletions(-) (limited to 'lib/safe-read.c') diff --git a/lib/safe-read.c b/lib/safe-read.c index 134b80454..e4cb1d3a2 100644 --- a/lib/safe-read.c +++ b/lib/safe-read.c @@ -1,4 +1,4 @@ -/* safe-read.c -- an interface to read that retries after interrupts +/* An interface to read that retries after interrupts. Copyright (C) 1993, 1994, 1998, 2002 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify @@ -13,16 +13,17 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if HAVE_CONFIG_H # include #endif -#include -#include +/* Specification. */ +#include "safe-read.h" +/* Get ssize_t. */ +#include #if HAVE_UNISTD_H # include #endif @@ -32,39 +33,47 @@ extern int errno; #endif -#include "safe-read.h" - -/* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted. - Return the actual number of bytes read, zero upon EOF, - or SAFE_READ_ERROR upon error. - Abort if LEN is SAFE_READ_ERROR (aka `(size_t) -1'). +#include - WARNING: although both LEN and the return value are of type size_t, - the range of the return value is restricted -- by virtue of being - returned from read(2) -- and will never be larger than SSIZE_MAX, - with the exception of SAFE_READ_ERROR, of course. - So don't test `safe_read (..., N) == N' unless you're sure that - N <= SSIZE_MAX. */ +/* 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 +/* 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. */ size_t -safe_read (int desc, void *ptr, size_t len) +safe_read (int fd, void *buf, size_t count) { - ssize_t n_chars; + size_t total_read = 0; + char *ptr = buf; - if (len == SAFE_READ_ERROR) - abort (); - if (len == 0) - return len; + while (count > 0) + { + 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 - do - { - n_chars = read (desc, ptr, len); - } - while (n_chars < 0 && errno == EINTR); -#else - n_chars = read (desc, ptr, len); + if (errno == EINTR) + continue; #endif + return SAFE_READ_ERROR; + } + total_read += result; + ptr += result; + count -= result; + } - return n_chars; + return total_read; } -- cgit v1.2.3-54-g00ecf