diff -r df914f383f5c -r 219c7ea94a42 librazor/util.c --- a/librazor/util.c Thu Oct 09 17:27:41 2014 +0100 +++ b/librazor/util.c Fri Jun 10 17:54:20 2016 +0100 @@ -62,6 +62,19 @@ return p; } +#if HAVE_SYS_MMAN_H +#define OPEN_FILE_USED (1U<<0) +#define OPEN_FILE_MMAPPED (1U<<1) + +struct open_file { + void *addr; + size_t length; + uint32_t flags; +}; + +struct array open_files = { 0, }; +#endif /* HAVE_SYS_MMAN_H */ + void * razor_file_get_contents(const char *filename, size_t *length, int private, struct razor_error **error) @@ -71,6 +84,9 @@ void *addr = NULL; size_t nb; ssize_t res; +#if HAVE_SYS_MMAN_H + struct open_file *of, *ofend; +#endif fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) { @@ -85,16 +101,31 @@ } *length = st.st_size; + #if HAVE_SYS_MMAN_H + ofend = open_files.data + open_files.size; + for (of = open_files.data; of < ofend; of++) + if (!(of->flags & OPEN_FILE_USED)) + break; + if (of == ofend) { + of = array_add(&open_files, sizeof *of); + of->flags = 0; + } + if (!private) { addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) addr = NULL; + else + of->flags = OPEN_FILE_USED | OPEN_FILE_MMAPPED; } -#endif +#endif /* HAVE_SYS_MMAN_H */ if (!addr) { addr = malloc(st.st_size); if (addr) { +#if HAVE_SYS_MMAN_H + of->flags = OPEN_FILE_USED; +#endif nb = 0; while(nb < st.st_size) { res = read(fd, addr + nb, st.st_size - nb); @@ -112,17 +143,47 @@ } close(fd); +#if HAVE_SYS_MMAN_H + of->addr = addr; + of->length = st.st_size; +#endif + return addr; } int razor_file_free_contents(void *addr, size_t length) { #if HAVE_SYS_MMAN_H - return munmap(addr, length); -#else + int retval, mmapped; + struct open_file *of, *ofend; + + ofend = open_files.data + open_files.size; + for (of = open_files.data; of < ofend; of++) + if ((of->flags & OPEN_FILE_USED) && of->addr == addr) + break; + + if (of == ofend) + return 1; + + length = of->length; + mmapped = of->flags & OPEN_FILE_MMAPPED; + of->flags &= ~OPEN_FILE_USED; + + for (of = open_files.data; of < ofend; of++) + if (of->flags & OPEN_FILE_USED) + break; + + if (of == ofend) { + array_release(&open_files); + array_init(&open_files); + } + + if (mmapped) + return munmap(addr, length); +#endif + free(addr); return 0; -#endif } struct qsort_context {