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 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