xref: /dflybsd-src/contrib/grep/lib/safe-read.c (revision 91b9ed38d3db6a8a8ac5b66da1d43e6e331e259a)
1680a9cb8SJohn Marino /* An interface to read and write that retries after interrupts.
2680a9cb8SJohn Marino 
3*09d4459fSDaniel Fojt    Copyright (C) 1993-1994, 1998, 2002-2006, 2009-2020 Free Software
4680a9cb8SJohn Marino    Foundation, Inc.
5680a9cb8SJohn Marino 
6680a9cb8SJohn Marino    This program is free software: you can redistribute it and/or modify
7680a9cb8SJohn Marino    it under the terms of the GNU General Public License as published by
8680a9cb8SJohn Marino    the Free Software Foundation; either version 3 of the License, or
9680a9cb8SJohn Marino    (at your option) any later version.
10680a9cb8SJohn Marino 
11680a9cb8SJohn Marino    This program is distributed in the hope that it will be useful,
12680a9cb8SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
13680a9cb8SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14680a9cb8SJohn Marino    GNU General Public License for more details.
15680a9cb8SJohn Marino 
16680a9cb8SJohn Marino    You should have received a copy of the GNU General Public License
17*09d4459fSDaniel Fojt    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
18680a9cb8SJohn Marino 
19680a9cb8SJohn Marino #include <config.h>
20680a9cb8SJohn Marino 
21680a9cb8SJohn Marino /* Specification.  */
22680a9cb8SJohn Marino #ifdef SAFE_WRITE
23680a9cb8SJohn Marino # include "safe-write.h"
24680a9cb8SJohn Marino #else
25680a9cb8SJohn Marino # include "safe-read.h"
26680a9cb8SJohn Marino #endif
27680a9cb8SJohn Marino 
28680a9cb8SJohn Marino /* Get ssize_t.  */
29680a9cb8SJohn Marino #include <sys/types.h>
30680a9cb8SJohn Marino #include <unistd.h>
31680a9cb8SJohn Marino 
32680a9cb8SJohn Marino #include <errno.h>
33680a9cb8SJohn Marino 
34680a9cb8SJohn Marino #ifdef EINTR
35680a9cb8SJohn Marino # define IS_EINTR(x) ((x) == EINTR)
36680a9cb8SJohn Marino #else
37680a9cb8SJohn Marino # define IS_EINTR(x) 0
38680a9cb8SJohn Marino #endif
39680a9cb8SJohn Marino 
40*09d4459fSDaniel Fojt #include "sys-limits.h"
41680a9cb8SJohn Marino 
42680a9cb8SJohn Marino #ifdef SAFE_WRITE
43680a9cb8SJohn Marino # define safe_rw safe_write
44680a9cb8SJohn Marino # define rw write
45680a9cb8SJohn Marino #else
46680a9cb8SJohn Marino # define safe_rw safe_read
47680a9cb8SJohn Marino # define rw read
48680a9cb8SJohn Marino # undef const
49680a9cb8SJohn Marino # define const /* empty */
50680a9cb8SJohn Marino #endif
51680a9cb8SJohn Marino 
52680a9cb8SJohn Marino /* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if
53680a9cb8SJohn Marino    interrupted.  Return the actual number of bytes read(written), zero for EOF,
54680a9cb8SJohn Marino    or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error.  */
55680a9cb8SJohn Marino size_t
safe_rw(int fd,void const * buf,size_t count)56680a9cb8SJohn Marino safe_rw (int fd, void const *buf, size_t count)
57680a9cb8SJohn Marino {
58680a9cb8SJohn Marino   for (;;)
59680a9cb8SJohn Marino     {
60680a9cb8SJohn Marino       ssize_t result = rw (fd, buf, count);
61680a9cb8SJohn Marino 
62680a9cb8SJohn Marino       if (0 <= result)
63680a9cb8SJohn Marino         return result;
64680a9cb8SJohn Marino       else if (IS_EINTR (errno))
65680a9cb8SJohn Marino         continue;
66*09d4459fSDaniel Fojt       else if (errno == EINVAL && SYS_BUFSIZE_MAX < count)
67*09d4459fSDaniel Fojt         count = SYS_BUFSIZE_MAX;
68680a9cb8SJohn Marino       else
69680a9cb8SJohn Marino         return result;
70680a9cb8SJohn Marino     }
71680a9cb8SJohn Marino }
72