1
2
3
4
5
6
7
8
9#include "libbb.h"
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48ssize_t FAST_FUNC nonblock_immune_read(int fd, void *buf, size_t count)
49{
50 struct pollfd pfd[1];
51 ssize_t n;
52
53 while (1) {
54 n = safe_read(fd, buf, count);
55 if (n >= 0 || errno != EAGAIN)
56 return n;
57
58 pfd[0].fd = fd;
59 pfd[0].events = POLLIN;
60
61 safe_poll(pfd, 1, -1);
62 }
63}
64
65
66
67
68char* FAST_FUNC xmalloc_reads(int fd, size_t *maxsz_p)
69{
70 char *p;
71 char *buf = NULL;
72 size_t sz = 0;
73 size_t maxsz = maxsz_p ? *maxsz_p : (INT_MAX - 4095);
74
75 goto jump_in;
76
77 while (sz < maxsz) {
78 if ((size_t)(p - buf) == sz) {
79 jump_in:
80 buf = xrealloc(buf, sz + 128);
81 p = buf + sz;
82 sz += 128;
83 }
84 if (nonblock_immune_read(fd, p, 1) != 1) {
85
86 if (p == buf) {
87 free(buf);
88 return NULL;
89 }
90 break;
91 }
92 if (*p == '\n')
93 break;
94 p++;
95 }
96 *p = '\0';
97 if (maxsz_p)
98 *maxsz_p = p - buf;
99 p++;
100 return xrealloc(buf, p - buf);
101}
102
103
104
105void* FAST_FUNC xmalloc_read_with_initial_buf(int fd, size_t *maxsz_p, char *buf, size_t total)
106{
107 size_t size, rd_size;
108 size_t to_read;
109 struct stat st;
110
111 to_read = maxsz_p ? *maxsz_p : (INT_MAX - 4095);
112
113
114 st.st_size = 0;
115 fstat(fd, &st);
116
117
118 size = (st.st_size | 0x3ff) + 1;
119
120 while (1) {
121 if (to_read < size)
122 size = to_read;
123 buf = xrealloc(buf, total + size + 1);
124 rd_size = full_read(fd, buf + total, size);
125 if ((ssize_t)rd_size == (ssize_t)(-1)) {
126 free(buf);
127 return NULL;
128 }
129 total += rd_size;
130 if (rd_size < size)
131 break;
132 if (to_read <= rd_size)
133 break;
134 to_read -= rd_size;
135
136 size = ((total / 8) | 0x3ff) + 1;
137 if (size > 64*1024)
138 size = 64*1024;
139 }
140 buf = xrealloc(buf, total + 1);
141 buf[total] = '\0';
142
143 if (maxsz_p)
144 *maxsz_p = total;
145 return buf;
146}
147
148void* FAST_FUNC xmalloc_read(int fd, size_t *maxsz_p)
149{
150 return xmalloc_read_with_initial_buf(fd, maxsz_p, NULL, 0);
151}
152
153#ifdef USING_LSEEK_TO_GET_SIZE
154
155
156
157
158
159
160
161void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *maxsz_p)
162{
163 char *buf;
164 size_t size;
165 int fd;
166 off_t len;
167
168 fd = open(filename, O_RDONLY);
169 if (fd < 0)
170 return NULL;
171
172
173
174 size = 0x3ff;
175 len = lseek(fd, 0, SEEK_END) | 0x3ff;
176 if (len != (off_t)-1) {
177 xlseek(fd, 0, SEEK_SET);
178 size = maxsz_p ? *maxsz_p : (INT_MAX - 4095);
179 if (len < size)
180 size = len;
181 }
182
183 buf = xmalloc(size + 1);
184 size = read_close(fd, buf, size);
185 if ((ssize_t)size < 0) {
186 free(buf);
187 return NULL;
188 }
189 buf = xrealloc(buf, size + 1);
190 buf[size] = '\0';
191
192 if (maxsz_p)
193 *maxsz_p = size;
194 return buf;
195}
196#endif
197
198
199
200void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *maxsz_p)
201{
202 char *buf;
203 int fd;
204
205 fd = open(filename, O_RDONLY);
206 if (fd < 0)
207 return NULL;
208
209 buf = xmalloc_read(fd, maxsz_p);
210 close(fd);
211 return buf;
212}
213
214
215void FAST_FUNC xread(int fd, void *buf, size_t count)
216{
217 if (count) {
218 ssize_t size = full_read(fd, buf, count);
219 if ((size_t)size != count)
220 bb_simple_error_msg_and_die("short read");
221 }
222}
223
224
225unsigned char FAST_FUNC xread_char(int fd)
226{
227 char tmp;
228 xread(fd, &tmp, 1);
229 return tmp;
230}
231
232void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p)
233{
234 void *buf = xmalloc_open_read_close(filename, maxsz_p);
235 if (!buf)
236 bb_perror_msg_and_die("can't read '%s'", filename);
237 return buf;
238}
239