diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2023-05-17 18:37:41 +0200 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2023-05-17 18:37:45 +0200 |
commit | 3acfb083365a33a377f437a9a2e41d545d91ddfb (patch) | |
tree | 918b4e37ff5ef48a543856da37b419749cd707bf | |
parent | signal: refactoring (diff) | |
download | cimple-3acfb083365a33a377f437a9a2e41d545d91ddfb.tar.gz cimple-3acfb083365a33a377f437a9a2e41d545d91ddfb.zip |
file: rework file_read
It now increases the buffer size exponentially until it finishes reading
the file.
-rw-r--r-- | src/file.c | 45 | ||||
-rw-r--r-- | src/file.h | 2 |
2 files changed, 20 insertions, 27 deletions
@@ -104,43 +104,36 @@ int file_exists(const char *path) return !ret && S_ISREG(stat.st_mode); } -int file_read(int fd, char **_contents, size_t *_len) +int file_read(int fd, char **_contents, size_t *_size) { - char buf[128]; - size_t buf_len = sizeof(buf) / sizeof(buf[0]); - int ret = 0; - + size_t alloc_size = 256; char *contents = NULL; - size_t len = 0; + size_t size = 0; while (1) { - ssize_t read_now = read(fd, buf, buf_len); + contents = realloc(contents, alloc_size); + if (!contents) + return -1; - if (read_now < 0) { + ssize_t read_size = read(fd, contents + size, alloc_size - size - 1); + + if (read_size < 0) { log_errno("read"); - ret = read_now; - goto free_output; + free(contents); + return read_size; } - if (!read_now) { + if (!read_size) { *_contents = contents; - *_len = len; - goto exit; + *_size = size; + return 0; } - contents = realloc(contents, len + read_now + 1); - if (!contents) { - log_errno("realloc"); - return -1; + size += read_size; + contents[size] = '\0'; + + if (size == alloc_size - 1) { + alloc_size *= 2; } - memcpy(contents + len, buf, read_now); - len += read_now; - contents[len] = '\0'; } - -free_output: - free(contents); - -exit: - return ret; } @@ -16,6 +16,6 @@ int my_chdir(const char *dir, char **old); char *my_readlink(const char *path); int file_exists(const char *path); -int file_read(int fd, char **output, size_t *len); +int file_read(int fd, char **output, size_t *size); #endif |