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(int fd, size_t *maxsz_p)
106{
107 char *buf;
108 size_t size, rd_size, total;
109 size_t to_read;
110 struct stat st;
111
112 to_read = maxsz_p ? *maxsz_p : (INT_MAX - 4095);
113
114
115 st.st_size = 0;
116 fstat(fd, &st);
117
118
119 size = (st.st_size | 0x3ff) + 1;
120
121 total = 0;
122 buf = NULL;
123 while (1) {
124 if (to_read < size)
125 size = to_read;
126 buf = xrealloc(buf, total + size + 1);
127 rd_size = full_read(fd, buf + total, size);
128 if ((ssize_t)rd_size == (ssize_t)(-1)) {
129 free(buf);
130 return NULL;
131 }
132 total += rd_size;
133 if (rd_size < size)
134 break;
135 if (to_read <= rd_size)
136 break;
137 to_read -= rd_size;
138
139 size = ((total / 8) | 0x3ff) + 1;
140 if (size > 64*1024)
141 size = 64*1024;
142 }
143 buf = xrealloc(buf, total + 1);
144 buf[total] = '\0';
145
146 if (maxsz_p)
147 *maxsz_p = total;
148 return buf;
149}
150
151#ifdef USING_LSEEK_TO_GET_SIZE
152
153
154
155
156
157
158
159void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *maxsz_p)
160{
161 char *buf;
162 size_t size;
163 int fd;
164 off_t len;
165
166 fd = open(filename, O_RDONLY);
167 if (fd < 0)
168 return NULL;
169
170
171
172 size = 0x3ff;
173 len = lseek(fd, 0, SEEK_END) | 0x3ff;
174 if (len != (off_t)-1) {
175 xlseek(fd, 0, SEEK_SET);
176 size = maxsz_p ? *maxsz_p : (INT_MAX - 4095);
177 if (len < size)
178 size = len;
179 }
180
181 buf = xmalloc(size + 1);
182 size = read_close(fd, buf, size);
183 if ((ssize_t)size < 0) {
184 free(buf);
185 return NULL;
186 }
187 buf = xrealloc(buf, size + 1);
188 buf[size] = '\0';
189
190 if (maxsz_p)
191 *maxsz_p = size;
192 return buf;
193}
194#endif
195
196
197
198void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *maxsz_p)
199{
200 char *buf;
201 int fd;
202
203 fd = open(filename, O_RDONLY);
204 if (fd < 0)
205 return NULL;
206
207 buf = xmalloc_read(fd, maxsz_p);
208 close(fd);
209 return buf;
210}
211
212
213void FAST_FUNC xread(int fd, void *buf, size_t count)
214{
215 if (count) {
216 ssize_t size = full_read(fd, buf, count);
217 if ((size_t)size != count)
218 bb_error_msg_and_die("short read");
219 }
220}
221
222
223unsigned char FAST_FUNC xread_char(int fd)
224{
225 char tmp;
226 xread(fd, &tmp, 1);
227 return tmp;
228}
229
230void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p)
231{
232 void *buf = xmalloc_open_read_close(filename, maxsz_p);
233 if (!buf)
234 bb_perror_msg_and_die("can't read '%s'", filename);
235 return buf;
236}
237