From 0a1446275d88946734417ed96a3c0f1d7ea969e4 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sun, 20 Apr 2008 14:45:43 +0000 Subject: [PATCH] xmalloc_open_read_close: use fstat to get file size (instead of lseek). by Joakim Tjernlund function old new delta xmalloc_open_read_close 190 181 -9 --- libbb/read.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/libbb/read.c b/libbb/read.c index e5f140f3b..288358d79 100644 --- a/libbb/read.c +++ b/libbb/read.c @@ -203,6 +203,48 @@ ssize_t open_read_close(const char *filename, void *buf, size_t size) return read_close(fd, buf, size); } +// Read (potentially big) files in one go. File size is estimated by +// lseek to end. +void *xmalloc_open_read_close(const char *filename, size_t *sizep) +{ + char *buf; + size_t size; + int fd; + off_t len; + struct stat st; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return NULL; + + st.st_size = 0; /* in case fstat fail, define to 0 */ + fstat(fd, &st); + /* /proc/N/stat files report len 0 here */ + /* In order to make such files readable, we add small const */ + len = st.st_size | 0x3ff; /* read only 1k on unseekable files */ + size = sizep ? *sizep : INT_MAX; + if (len < size) + size = len; + buf = xmalloc(size + 1); + size = read_close(fd, buf, size); + if ((ssize_t)size < 0) { + free(buf); + return NULL; + } + xrealloc(buf, size + 1); + buf[size] = '\0'; + + if (sizep) + *sizep = size; + return buf; +} + +#ifdef USING_LSEEK_TO_GET_SIZE +/* Alternatively, file size can be obtained by lseek to the end. + * The code is slightly bigger. Retained in case fstat approach + * will not work for some weird cases (/proc, block devices, etc). + * (NB: lseek also can fail to work for some weird files) */ + // Read (potentially big) files in one go. File size is estimated by // lseek to end. void *xmalloc_open_read_close(const char *filename, size_t *sizep) @@ -240,6 +282,7 @@ void *xmalloc_open_read_close(const char *filename, size_t *sizep) *sizep = size; return buf; } +#endif void *xmalloc_xopen_read_close(const char *filename, size_t *sizep) {