diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2020-09-24 22:10:03 -0700 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2020-09-24 22:10:03 -0700 |
| commit | f5257e1823d0354666d8cbe72738d5821b461e4f (patch) | |
| tree | 8c5e5ac3d0e8dea76b380d23b7f4a07c6e599bd9 /file_loader.c | |
| parent | f6d8bc304f287adfac43d06506cd86f354d4d5f1 (diff) | |
Added mmap()
Diffstat (limited to 'file_loader.c')
| -rw-r--r-- | file_loader.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/file_loader.c b/file_loader.c index 0ce4b4c..82f594b 100644 --- a/file_loader.c +++ b/file_loader.c @@ -7,6 +7,8 @@ #include <limits.h> #include <stdlib.h> #include <string.h> +#include <sys/mman.h> +#include <sys/stat.h> #include <unistd.h> #include "file_loader.h" @@ -22,19 +24,33 @@ file_t *load_file(const char *filename) file_t *f = calloc(sizeof(file_t), 1); f->filename = strdup(filename); // TODO: use mmap when possible + struct stat sb; + if (fstat(fd, &sb) == -1) + goto skip_mmap; + + f->contents = mmap(NULL, (size_t)sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (f->contents == MAP_FAILED) + goto skip_mmap; + + f->mmapped = 1; + f->length = (size_t)sb.st_size; + goto finished_loading; + + skip_mmap: f->mmapped = 0; size_t capacity = 1000; f->length = 0; - f->contents = calloc(sizeof(char), capacity+1); + f->contents = calloc(sizeof(char), capacity); ssize_t just_read; while ((just_read=read(fd, &f->contents[f->length], capacity - f->length)) > 0) { f->length += (size_t)just_read; if (f->length >= capacity) f->contents = realloc(f->contents, sizeof(char)*(capacity *= 2) + 1); } - f->contents[f->length] = '\0'; - f->end = &f->contents[f->length]; close(fd); + + finished_loading: + f->end = &f->contents[f->length]; // Calculate line numbers: size_t linecap = 10; @@ -64,7 +80,11 @@ void destroy_file(file_t **f) (*f)->lines = NULL; } if ((*f)->contents) { - free((*f)->contents); + if ((*f)->mmapped) { + munmap((*f)->contents, (*f)->length); + } else { + free((*f)->contents); + } (*f)->contents = NULL; } free(*f); |
