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