Add malloc_read_whole_file()

Use to implement read_whole_file()
This commit is contained in:
Andrew Bettison 2014-04-29 12:36:58 +09:30
parent c17fb19bd4
commit c222727a46
2 changed files with 34 additions and 5 deletions

29
os.c
View File

@ -20,9 +20,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define __SERVAL_DNA__OS_INLINE
#include "constants.h"
#include "os.h"
#include "mem.h"
#include "str.h"
#include "log.h"
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
@ -181,6 +183,15 @@ ssize_t read_symlink(const char *path, char *buf, size_t len)
}
ssize_t read_whole_file(const char *path, unsigned char *buffer, size_t buffer_size)
{
assert(buffer != NULL);
assert(buffer_size != 0);
if (malloc_read_whole_file(path, &buffer, &buffer_size) == -1)
return -1;
return buffer_size;
}
int malloc_read_whole_file(const char *path, unsigned char **bufp, size_t *sizp)
{
int fd = open(path, O_RDONLY);
if (fd == -1)
@ -189,12 +200,20 @@ ssize_t read_whole_file(const char *path, unsigned char *buffer, size_t buffer_s
struct stat stat;
if (fstat(fd, &stat) == -1)
ret = WHYF_perror("fstat(%d)", fd);
else if ((size_t)stat.st_size > buffer_size)
ret = WHYF("file %s (size %zu) is larger than available buffer (%zu)", alloca_str_toprint(path), (size_t)stat.st_size, buffer_size);
else if (*bufp != NULL && (size_t)stat.st_size > *sizp)
ret = WHYF("file %s (size %zu) is larger than available buffer (%zu)", alloca_str_toprint(path), (size_t)stat.st_size, *sizp);
else if (*bufp == NULL && *sizp && (size_t)stat.st_size > *sizp)
ret = WHYF("file %s (size %zu) is larger than maximum buffer (%zu)", alloca_str_toprint(path), (size_t)stat.st_size, *sizp);
else {
ret = read(fd, buffer, buffer_size);
if (ret == -1)
ret = WHYF_perror("read(%d,%s,%zu)", fd, alloca_str_toprint(path), buffer_size);
*sizp = (size_t)stat.st_size;
if (*bufp == NULL && (*bufp = emalloc(*sizp)) == NULL)
ret = WHYF("file %s (size %zu) does not fit into memory", alloca_str_toprint(path), *sizp);
else {
assert(*bufp != NULL);
ret = read(fd, *bufp, *sizp);
if (ret == -1)
ret = WHYF_perror("read(%d,%s,%zu)", fd, alloca_str_toprint(path), *sizp);
}
}
if (close(fd) == -1)
ret = WHYF_perror("close(%d)", fd);

10
os.h
View File

@ -166,4 +166,14 @@ ssize_t read_symlink(const char *path, char *buf, size_t len);
*/
ssize_t read_whole_file(const char *path, unsigned char *buffer, size_t buffer_size);
/* Read the whole file into a buffer. If *bufp is NULL then uses malloc(3) to
* create a buffer first, the size of the file (up to a maximum of *sizp if
* *sizp is not zero), and assigns the address to *bufp. If the file will not
* fit into the buffer or if there is an error from malloc(3) or opening or
* reading the file, logs an error and returns -1. Otherwise, returns 0.
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
int malloc_read_whole_file(const char *path, unsigned char **bufp, size_t *sizp);
#endif //__SERVAL_DNA__OS_H