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
This commit is contained in:
parent
fe493479e2
commit
0a1446275d
43
libbb/read.c
43
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);
|
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
|
// Read (potentially big) files in one go. File size is estimated by
|
||||||
// lseek to end.
|
// lseek to end.
|
||||||
void *xmalloc_open_read_close(const char *filename, size_t *sizep)
|
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;
|
*sizep = size;
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void *xmalloc_xopen_read_close(const char *filename, size_t *sizep)
|
void *xmalloc_xopen_read_close(const char *filename, size_t *sizep)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user