(IS_EINTR): Define.
[gnulib.git] / lib / safe-read.c
1 /* An interface to read that retries after interrupts.
2    Copyright (C) 1993, 1994, 1998, 2002 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 #if HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 /* Specification.  */
23 #include "safe-read.h"
24
25 /* Get ssize_t.  */
26 #include <sys/types.h>
27 #if HAVE_UNISTD_H
28 # include <unistd.h>
29 #endif
30
31 #include <errno.h>
32 #ifndef errno
33 extern int errno;
34 #endif
35
36 #ifdef EINTR
37 # define IS_EINTR(x) ((x) == EINTR)
38 #else
39 # define IS_EINTR(x) 0
40 #endif
41
42 #include <limits.h>
43
44 #ifndef CHAR_BIT
45 # define CHAR_BIT 8
46 #endif
47
48 /* The extra casts work around common compiler bugs.  */
49 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
50 /* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
51    It is necessary at least when t == time_t.  */
52 #define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
53                               ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
54 #define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
55
56 #ifndef INT_MAX
57 # define INT_MAX TYPE_MAXIMUM (int)
58 #endif
59
60 /* We don't pass an nbytes count > SSIZE_MAX to read() - POSIX says the
61    effect would be implementation-defined.  Also we don't pass an nbytes
62    count > INT_MAX but <= SSIZE_MAX to read() - this triggers a bug in
63    Tru64 5.1.  */
64 #define MAX_BYTES_TO_READ INT_MAX
65
66 /* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted.
67    Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR
68    upon error.  */
69 size_t
70 safe_read (int fd, void *buf, size_t count)
71 {
72   size_t nbytes_to_read = count;
73   ssize_t result;
74
75   /* Limit the number of bytes to read, to avoid running into unspecified
76      behaviour.  But keep the file pointer block aligned when doing so.
77      Note that in this case we don't need to call read() multiple times here,
78      because the caller is prepared to partial results.  */
79   if (nbytes_to_read > MAX_BYTES_TO_READ)
80     nbytes_to_read = MAX_BYTES_TO_READ & ~8191;
81
82   do
83     {
84       result = read (fd, buf, nbytes_to_read);
85     }
86   while (result < 0 && IS_EINTR (errno));
87
88   return (size_t) result;
89 }