aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/file.c
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2023-05-17 18:37:41 +0200
committerEgor Tensin <Egor.Tensin@gmail.com>2023-05-17 18:37:45 +0200
commit3acfb083365a33a377f437a9a2e41d545d91ddfb (patch)
tree918b4e37ff5ef48a543856da37b419749cd707bf /src/file.c
parentsignal: refactoring (diff)
downloadcimple-3acfb083365a33a377f437a9a2e41d545d91ddfb.tar.gz
cimple-3acfb083365a33a377f437a9a2e41d545d91ddfb.zip
file: rework file_read
It now increases the buffer size exponentially until it finishes reading the file.
Diffstat (limited to 'src/file.c')
-rw-r--r--src/file.c45
1 files changed, 19 insertions, 26 deletions
diff --git a/src/file.c b/src/file.c
index cea6794..bdc0e22 100644
--- a/src/file.c
+++ b/src/file.c
@@ -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;
}