]> git.ipfire.org Git - thirdparty/util-linux.git/blob - include/all-io.h
nsenter: add --env for allowing environment variables inheritance
[thirdparty/util-linux.git] / include / all-io.h
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
9 #ifndef UTIL_LINUX_ALL_IO_H
10 #define UTIL_LINUX_ALL_IO_H
11
12 #include <string.h>
13 #include <unistd.h>
14 #include <errno.h>
15 #include <sys/types.h>
16 #ifdef HAVE_SYS_SENDFILE_H
17 # include <sys/sendfile.h>
18 #endif
19
20 #include "c.h"
21
22 static inline int write_all(int fd, const void *buf, size_t count)
23 {
24 while (count) {
25 ssize_t tmp;
26
27 errno = 0;
28 tmp = write(fd, buf, count);
29 if (tmp > 0) {
30 count -= tmp;
31 if (count)
32 buf = (const void *) ((const char *) buf + tmp);
33 } else if (errno != EINTR && errno != EAGAIN)
34 return -1;
35 if (errno == EAGAIN) /* Try later, *sigh* */
36 xusleep(250000);
37 }
38 return 0;
39 }
40
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)
52 ptr = (const void *) ((const char *) ptr + (tmp * size));
53 } else if (errno != EINTR && errno != EAGAIN)
54 return -1;
55 if (errno == EAGAIN) /* Try later, *sigh* */
56 xusleep(250000);
57 }
58 return 0;
59 }
60
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);
70 if (ret < 0) {
71 if ((errno == EAGAIN || errno == EINTR) && (tries++ < 5)) {
72 xusleep(250000);
73 continue;
74 }
75 return c ? c : -1;
76 }
77 if (ret == 0)
78 return c;
79 tries = 0;
80 count -= ret;
81 buf += ret;
82 c += ret;
83 }
84 return c;
85 }
86
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
117 static inline ssize_t sendfile_all(int out, int in, off_t *off, size_t count)
118 {
119 #if defined(HAVE_SENDFILE) && defined(__linux__)
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 }
144 #endif /* UTIL_LINUX_ALL_IO_H */