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