1 /* An interface to read and write that retries (if necessary) until complete. 2 3 Copyright (C) 1993-1994, 1997-2006, 2009-2021 Free Software Foundation, Inc. 4 5 This file is free software: you can redistribute it and/or modify 6 it under the terms of the GNU Lesser General Public License as 7 published by the Free Software Foundation; either version 2.1 of the 8 License, or (at your option) any later version. 9 10 This file is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public License 16 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 17 18 #include <config.h> 19 20 /* Specification. */ 21 #ifdef FULL_READ 22 # include "full-read.h" 23 #else 24 # include "full-write.h" 25 #endif 26 27 #include <errno.h> 28 29 #ifdef FULL_READ 30 # include "safe-read.h" 31 # define safe_rw safe_read 32 # define full_rw full_read 33 # undef const 34 # define const /* empty */ 35 #else 36 # include "safe-write.h" 37 # define safe_rw safe_write 38 # define full_rw full_write 39 #endif 40 41 #ifdef FULL_READ 42 /* Set errno to zero upon EOF. */ 43 # define ZERO_BYTE_TRANSFER_ERRNO 0 44 #else 45 /* Some buggy drivers return 0 when one tries to write beyond 46 a device's end. (Example: Linux 1.2.13 on /dev/fd0.) 47 Set errno to ENOSPC so they get a sensible diagnostic. */ 48 # define ZERO_BYTE_TRANSFER_ERRNO ENOSPC 49 #endif 50 51 /* Write(read) COUNT bytes at BUF to(from) descriptor FD, retrying if 52 interrupted or if a partial write(read) occurs. Return the number 53 of bytes transferred. 54 When writing, set errno if fewer than COUNT bytes are written. 55 When reading, if fewer than COUNT bytes are read, you must examine 56 errno to distinguish failure from EOF (errno == 0). */ 57 size_t 58 full_rw (int fd, const void *buf, size_t count) /* */ 59 { 60 size_t total = 0; 61 const char *ptr = (const char *) buf; 62 63 while (count > 0) 64 { 65 size_t n_rw = safe_rw (fd, ptr, count); 66 if (n_rw == (size_t) -1) 67 break; 68 if (n_rw == 0) 69 { 70 errno = ZERO_BYTE_TRANSFER_ERRNO; 71 break; 72 } 73 total += n_rw; 74 ptr += n_rw; 75 count -= n_rw; 76 } 77 78 return total; 79 }