From: Joel Rosdahl Date: Thu, 26 Aug 2010 19:09:02 +0000 (+0200) Subject: Implement read_file() for reading an arbitrary file into memory X-Git-Tag: v3.1~51 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0d160410924e0d3b9d197ccba5b3d1b883e289bc;p=thirdparty%2Fccache.git Implement read_file() for reading an arbitrary file into memory --- diff --git a/ccache.h b/ccache.h index 449acda32..6f7430f0a 100644 --- a/ccache.h +++ b/ccache.h @@ -149,6 +149,7 @@ int x_munmap(void *addr, size_t length); int x_rename(const char *oldpath, const char *newpath); char *x_readlink(const char *path); char *read_text_file(const char *path); +int read_file(const char *path, size_t size_hint, char **data, size_t *size); /* ------------------------------------------------------------------------- */ /* stats.c */ diff --git a/util.c b/util.c index 62107be37..31d497723 100644 --- a/util.c +++ b/util.c @@ -1158,33 +1158,55 @@ x_readlink(const char *path) } #endif -/* Return the content of a text file, or NULL on error. Caller frees. */ -char * -read_text_file(const char *path) +/* + * Reads the content of a file. Size hint 0 means no hint. Returns 0 on + * failure, otherwise 1. + */ +int +read_file(const char *path, size_t size_hint, char **data, size_t *size) { int fd, ret; - size_t pos = 0, allocated = 1024; - char *result; + size_t pos = 0, allocated = (size_hint == 0) ? 16384 : size_hint; fd = open(path, O_RDONLY); if (fd == -1) { - return NULL; + return 0; } - result = x_malloc(allocated); + *data = x_malloc(allocated); ret = 0; do { pos += ret; if (pos > allocated / 2) { allocated *= 2; - result = realloc(result, allocated); + *data = realloc(*data, allocated); } - } while ((ret = read(fd, result + pos, allocated - pos - 1)) > 0); + } while ((ret = read(fd, *data + pos, allocated - pos)) > 0); close(fd); if (ret == -1) { - free(result); - return NULL; + cc_log("Failed reading %s", path); + free(*data); + return 0; } - result[pos] = '\0'; - return result; + *size = pos; + return 1; +} + +/* + * Return the content (with NUL termination) of a text file, or NULL on error. + * Caller frees. + */ +char * +read_text_file(const char *path) +{ + size_t size; + char *data; + + if (read_file(path, 0, &data, &size)) { + data = x_realloc(data, size + 1); + data[size] = '\0'; + return data; + } else { + return NULL; + } }