diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2014-07-30 10:54:16 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2014-08-07 06:13:52 +0200 |
commit | 28ce918d96f5de657e88eb54f87edf441ab2caa5 (patch) | |
tree | 18dd5a0bcdcbf3f41591e100949341813e8f20bb /lib/libfile.c | |
parent | 3cfa4bc00c61eca4c0986c793dd21b8b5271fd8f (diff) | |
download | barebox-28ce918d96f5de657e88eb54f87edf441ab2caa5.tar.gz barebox-28ce918d96f5de657e88eb54f87edf441ab2caa5.tar.xz |
read_file: introduce read_file_2
read_file has some limitations:
- It is not possible to check the error code since read_file returns
NULL for failure
- It is not possible to limit the buffer size to sensible limits.
This patch introduces read_file_2 which doesn't have these limitations.
read_file becomes a wrapper around read_file_2.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'lib/libfile.c')
-rw-r--r-- | lib/libfile.c | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/lib/libfile.c b/lib/libfile.c index b36537fae6..c6fb6d7157 100644 --- a/lib/libfile.c +++ b/lib/libfile.c @@ -116,55 +116,74 @@ out: EXPORT_SYMBOL_GPL(read_file_line); /** - * read_file - read a file to an allocated buffer + * read_file_2 - read a file to an allocated buffer * @filename: The filename to read * @size: After successful return contains the size of the file + * @outbuf: contains a pointer to the file data after successful return + * @max_size: The maximum size to read. Use FILESIZE_MAX for reading files + * of any size. * - * This function reads a file to an allocated buffer. - * Some TFTP servers do not transfer the size of a file. In this case - * a the file is first read to a temporary file. + * This function reads a file to an allocated buffer. At maximum @max_size + * bytes are read. The actual read size is returned in @size. -EFBIG is + * returned if the file is bigger than @max_size, but the buffer is read + * anyway up to @max_size in this case. Free the buffer with free() after + * usage. * - * Return: The buffer conataining the file or NULL on failure + * Return: 0 for success, or negative error code. -EFBIG is returned + * when the file has been bigger than max_size. */ -void *read_file(const char *filename, size_t *size) +int read_file_2(const char *filename, size_t *size, void **outbuf, + loff_t max_size) { int fd; struct stat s; void *buf = NULL; const char *tmpfile = "/.read_file_tmp"; int ret; + loff_t read_size; again: - if (stat(filename, &s)) - return NULL; + ret = stat(filename, &s); + if (ret) + return ret; + + if (max_size == FILESIZE_MAX) + read_size = s.st_size; + else + read_size = max_size; - if (s.st_size == FILESIZE_MAX) { + if (read_size == FILESIZE_MAX) { ret = copy_file(filename, tmpfile, 0); if (ret) - return NULL; + return ret; filename = tmpfile; goto again; } - buf = xzalloc(s.st_size + 1); + buf = xzalloc(read_size + 1); fd = open(filename, O_RDONLY); if (fd < 0) goto err_out; - ret = read_full(fd, buf, s.st_size); + ret = read_full(fd, buf, read_size); if (ret < 0) goto err_out1; close(fd); if (size) - *size = s.st_size; + *size = ret; if (filename == tmpfile) unlink(tmpfile); - return buf; + *outbuf = buf; + + if (read_size < s.st_size) + return -EFBIG; + else + return 0; err_out1: close(fd); @@ -174,6 +193,30 @@ err_out: if (filename == tmpfile) unlink(tmpfile); + return ret; +} +EXPORT_SYMBOL(read_file_2); + +/** + * read_file - read a file to an allocated buffer + * @filename: The filename to read + * @size: After successful return contains the size of the file + * + * This function reads a file to an allocated buffer. + * Some TFTP servers do not transfer the size of a file. In this case + * a the file is first read to a temporary file. + * + * Return: The buffer conataining the file or NULL on failure + */ +void *read_file(const char *filename, size_t *size) +{ + int ret; + void *buf; + + ret = read_file_2(filename, size, &buf, FILESIZE_MAX); + if (!ret) + return buf; + return NULL; } EXPORT_SYMBOL(read_file); |