safe-read.c revision 9663:ace9a2ac3683
1/* An interface to read and write that retries after interrupts. 2 3 Copyright (C) 1993, 1994, 1998, 2002, 2003, 2004, 2005, 2006 Free 4 Software Foundation, Inc. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software Foundation, 18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 19 20#include <config.h> 21 22/* Specification. */ 23#ifdef SAFE_WRITE 24# include "safe-write.h" 25#else 26# include "safe-read.h" 27#endif 28 29/* Get ssize_t. */ 30#include <sys/types.h> 31#include <unistd.h> 32 33#include <errno.h> 34 35#ifdef EINTR 36# define IS_EINTR(x) ((x) == EINTR) 37#else 38# define IS_EINTR(x) 0 39#endif 40 41#include <limits.h> 42 43#ifdef SAFE_WRITE 44# define safe_rw safe_write 45# define rw write 46#else 47# define safe_rw safe_read 48# define rw read 49# undef const 50# define const /* empty */ 51#endif 52 53/* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if 54 interrupted. Return the actual number of bytes read(written), zero for EOF, 55 or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error. */ 56size_t 57safe_rw (int fd, void const *buf, size_t count) 58{ 59 /* Work around a bug in Tru64 5.1. Attempting to read more than 60 INT_MAX bytes fails with errno == EINVAL. See 61 <http://lists.gnu.org/archive/html/bug-gnu-utils/2002-04/msg00010.html>. 62 When decreasing COUNT, keep it block-aligned. */ 63 enum { BUGGY_READ_MAXIMUM = INT_MAX & ~8191 }; 64 65 for (;;) 66 { 67 ssize_t result = rw (fd, buf, count); 68 69 if (0 <= result) 70 return result; 71 else if (IS_EINTR (errno)) 72 continue; 73 else if (errno == EINVAL && BUGGY_READ_MAXIMUM < count) 74 count = BUGGY_READ_MAXIMUM; 75 else 76 return result; 77 } 78} 79