diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-20 14:45:43 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-20 14:45:43 +0000 |
commit | 0a1446275d88946734417ed96a3c0f1d7ea969e4 (patch) | |
tree | 577ea76080a5251ad54418c2831213e64e02563d /libbb | |
parent | fe493479e2814f25edc270a5605678adbc90086a (diff) | |
download | busybox-w32-0a1446275d88946734417ed96a3c0f1d7ea969e4.tar.gz busybox-w32-0a1446275d88946734417ed96a3c0f1d7ea969e4.tar.bz2 busybox-w32-0a1446275d88946734417ed96a3c0f1d7ea969e4.zip |
xmalloc_open_read_close: use fstat to get file size (instead of lseek).
by Joakim Tjernlund <Joakim.Tjernlund AT transmode.se>
function old new delta
xmalloc_open_read_close 190 181 -9
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/read.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/libbb/read.c b/libbb/read.c index e5f140f3b..288358d79 100644 --- a/libbb/read.c +++ b/libbb/read.c | |||
@@ -211,6 +211,48 @@ void *xmalloc_open_read_close(const char *filename, size_t *sizep) | |||
211 | size_t size; | 211 | size_t size; |
212 | int fd; | 212 | int fd; |
213 | off_t len; | 213 | off_t len; |
214 | struct stat st; | ||
215 | |||
216 | fd = open(filename, O_RDONLY); | ||
217 | if (fd < 0) | ||
218 | return NULL; | ||
219 | |||
220 | st.st_size = 0; /* in case fstat fail, define to 0 */ | ||
221 | fstat(fd, &st); | ||
222 | /* /proc/N/stat files report len 0 here */ | ||
223 | /* In order to make such files readable, we add small const */ | ||
224 | len = st.st_size | 0x3ff; /* read only 1k on unseekable files */ | ||
225 | size = sizep ? *sizep : INT_MAX; | ||
226 | if (len < size) | ||
227 | size = len; | ||
228 | buf = xmalloc(size + 1); | ||
229 | size = read_close(fd, buf, size); | ||
230 | if ((ssize_t)size < 0) { | ||
231 | free(buf); | ||
232 | return NULL; | ||
233 | } | ||
234 | xrealloc(buf, size + 1); | ||
235 | buf[size] = '\0'; | ||
236 | |||
237 | if (sizep) | ||
238 | *sizep = size; | ||
239 | return buf; | ||
240 | } | ||
241 | |||
242 | #ifdef USING_LSEEK_TO_GET_SIZE | ||
243 | /* Alternatively, file size can be obtained by lseek to the end. | ||
244 | * The code is slightly bigger. Retained in case fstat approach | ||
245 | * will not work for some weird cases (/proc, block devices, etc). | ||
246 | * (NB: lseek also can fail to work for some weird files) */ | ||
247 | |||
248 | // Read (potentially big) files in one go. File size is estimated by | ||
249 | // lseek to end. | ||
250 | void *xmalloc_open_read_close(const char *filename, size_t *sizep) | ||
251 | { | ||
252 | char *buf; | ||
253 | size_t size; | ||
254 | int fd; | ||
255 | off_t len; | ||
214 | 256 | ||
215 | fd = open(filename, O_RDONLY); | 257 | fd = open(filename, O_RDONLY); |
216 | if (fd < 0) | 258 | if (fd < 0) |
@@ -240,6 +282,7 @@ void *xmalloc_open_read_close(const char *filename, size_t *sizep) | |||
240 | *sizep = size; | 282 | *sizep = size; |
241 | return buf; | 283 | return buf; |
242 | } | 284 | } |
285 | #endif | ||
243 | 286 | ||
244 | void *xmalloc_xopen_read_close(const char *filename, size_t *sizep) | 287 | void *xmalloc_xopen_read_close(const char *filename, size_t *sizep) |
245 | { | 288 | { |