]>
Commit | Line | Data |
---|---|---|
0f23ee0c KZ |
1 | /* |
2 | * No copyright is claimed. This code is in the public domain; do with | |
3 | * it what you wish. | |
4 | * | |
5 | * Written by Karel Zak <kzak@redhat.com> | |
6 | * Petr Uzel <petr.uzel@suse.cz> | |
7 | */ | |
8 | ||
e12c9866 PU |
9 | #ifndef UTIL_LINUX_ALL_IO_H |
10 | #define UTIL_LINUX_ALL_IO_H | |
77714312 KZ |
11 | |
12 | #include <string.h> | |
13 | #include <unistd.h> | |
14 | #include <errno.h> | |
212bde6c | 15 | #include <sys/types.h> |
782cc33a KZ |
16 | #ifdef HAVE_SYS_SENDFILE_H |
17 | # include <sys/sendfile.h> | |
212bde6c | 18 | #endif |
77714312 | 19 | |
2a31396a KZ |
20 | #include "c.h" |
21 | ||
77714312 KZ |
22 | static inline int write_all(int fd, const void *buf, size_t count) |
23 | { | |
330f5439 | 24 | while (count) { |
77714312 KZ |
25 | ssize_t tmp; |
26 | ||
27 | errno = 0; | |
28 | tmp = write(fd, buf, count); | |
29 | if (tmp > 0) { | |
30 | count -= tmp; | |
31 | if (count) | |
34708190 | 32 | buf = (const void *) ((const char *) buf + tmp); |
77714312 KZ |
33 | } else if (errno != EINTR && errno != EAGAIN) |
34 | return -1; | |
729def03 | 35 | if (errno == EAGAIN) /* Try later, *sigh* */ |
a5bd7939 | 36 | xusleep(250000); |
77714312 KZ |
37 | } |
38 | return 0; | |
39 | } | |
40 | ||
330f5439 KZ |
41 | static inline int fwrite_all(const void *ptr, size_t size, |
42 | size_t nmemb, FILE *stream) | |
43 | { | |
44 | while (nmemb) { | |
45 | size_t tmp; | |
46 | ||
47 | errno = 0; | |
48 | tmp = fwrite(ptr, size, nmemb, stream); | |
49 | if (tmp > 0) { | |
50 | nmemb -= tmp; | |
51 | if (nmemb) | |
34708190 | 52 | ptr = (const void *) ((const char *) ptr + (tmp * size)); |
330f5439 KZ |
53 | } else if (errno != EINTR && errno != EAGAIN) |
54 | return -1; | |
55 | if (errno == EAGAIN) /* Try later, *sigh* */ | |
a5bd7939 | 56 | xusleep(250000); |
330f5439 KZ |
57 | } |
58 | return 0; | |
59 | } | |
60 | ||
f80e9bc3 PU |
61 | static inline ssize_t read_all(int fd, char *buf, size_t count) |
62 | { | |
63 | ssize_t ret; | |
64 | ssize_t c = 0; | |
65 | int tries = 0; | |
66 | ||
67 | memset(buf, 0, count); | |
68 | while (count > 0) { | |
69 | ret = read(fd, buf, count); | |
418eb094 EC |
70 | if (ret < 0) { |
71 | if ((errno == EAGAIN || errno == EINTR) && (tries++ < 5)) { | |
a5bd7939 | 72 | xusleep(250000); |
f80e9bc3 | 73 | continue; |
a5bd7939 | 74 | } |
f80e9bc3 PU |
75 | return c ? c : -1; |
76 | } | |
418eb094 EC |
77 | if (ret == 0) |
78 | return c; | |
b2ce7d58 | 79 | tries = 0; |
f80e9bc3 PU |
80 | count -= ret; |
81 | buf += ret; | |
82 | c += ret; | |
83 | } | |
84 | return c; | |
85 | } | |
86 | ||
4e9ec856 | 87 | static inline ssize_t read_all_alloc(int fd, char **buf) |
88 | { | |
89 | size_t size = 1024, c = 0; | |
90 | ssize_t ret; | |
91 | ||
92 | *buf = malloc(size); | |
93 | if (!*buf) | |
94 | return -1; | |
95 | ||
96 | while (1) { | |
97 | ret = read_all(fd, *buf + c, size - c); | |
98 | if (ret < 0) { | |
99 | free(*buf); | |
100 | *buf = NULL; | |
101 | return -1; | |
102 | } | |
103 | ||
104 | if (ret == 0) | |
105 | return c; | |
106 | ||
107 | c += ret; | |
108 | if (c == size) { | |
109 | size *= 2; | |
110 | *buf = realloc(*buf, size); | |
111 | if (!*buf) | |
112 | return -1; | |
113 | } | |
114 | } | |
115 | } | |
116 | ||
212bde6c EC |
117 | static inline ssize_t sendfile_all(int out, int in, off_t *off, size_t count) |
118 | { | |
782cc33a | 119 | #if defined(HAVE_SENDFILE) && defined(__linux__) |
212bde6c EC |
120 | ssize_t ret; |
121 | ssize_t c = 0; | |
122 | int tries = 0; | |
123 | while (count) { | |
124 | ret = sendfile(out, in, off, count); | |
125 | if (ret < 0) { | |
126 | if ((errno == EAGAIN || errno == EINTR) && (tries++ < 5)) { | |
127 | xusleep(250000); | |
128 | continue; | |
129 | } | |
130 | return c ? c : -1; | |
131 | } | |
132 | if (ret == 0) | |
133 | return c; | |
134 | tries = 0; | |
135 | count -= ret; | |
136 | c += ret; | |
137 | } | |
138 | return c; | |
139 | #else | |
140 | errno = ENOSYS; | |
141 | return -1; | |
142 | #endif | |
143 | } | |
e12c9866 | 144 | #endif /* UTIL_LINUX_ALL_IO_H */ |