1.1 --- a/librazor/util.c Thu Oct 09 17:27:41 2014 +0100
1.2 +++ b/librazor/util.c Thu Apr 14 11:59:56 2016 +0100
1.3 @@ -62,6 +62,19 @@
1.4 return p;
1.5 }
1.6
1.7 +#if HAVE_SYS_MMAN_H
1.8 +#define OPEN_FILE_USED (1U<<0)
1.9 +#define OPEN_FILE_MMAPPED (1U<<1)
1.10 +
1.11 +struct open_file {
1.12 + void *addr;
1.13 + size_t length;
1.14 + uint32_t flags;
1.15 +};
1.16 +
1.17 +struct array open_files = { 0, };
1.18 +#endif /* HAVE_SYS_MMAN_H */
1.19 +
1.20 void *
1.21 razor_file_get_contents(const char *filename, size_t *length, int private,
1.22 struct razor_error **error)
1.23 @@ -71,6 +84,9 @@
1.24 void *addr = NULL;
1.25 size_t nb;
1.26 ssize_t res;
1.27 +#if HAVE_SYS_MMAN_H
1.28 + struct open_file *of, *ofend;
1.29 +#endif
1.30
1.31 fd = open(filename, O_RDONLY | O_BINARY);
1.32 if (fd < 0) {
1.33 @@ -85,16 +101,31 @@
1.34 }
1.35
1.36 *length = st.st_size;
1.37 +
1.38 #if HAVE_SYS_MMAN_H
1.39 + ofend = open_files.data + open_files.size;
1.40 + for (of = open_files.data; of < ofend; of++)
1.41 + if (!(of->flags & OPEN_FILE_USED))
1.42 + break;
1.43 + if (of == ofend) {
1.44 + of = array_add(&open_files, sizeof *of);
1.45 + of->flags = 0;
1.46 + }
1.47 +
1.48 if (!private) {
1.49 addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
1.50 if (addr == MAP_FAILED)
1.51 addr = NULL;
1.52 + else
1.53 + of->flags = OPEN_FILE_USED | OPEN_FILE_MMAPPED;
1.54 }
1.55 -#endif
1.56 +#endif /* HAVE_SYS_MMAN_H */
1.57 if (!addr) {
1.58 addr = malloc(st.st_size);
1.59 if (addr) {
1.60 +#if HAVE_SYS_MMAN_H
1.61 + of->flags = OPEN_FILE_USED;
1.62 +#endif
1.63 nb = 0;
1.64 while(nb < st.st_size) {
1.65 res = read(fd, addr + nb, st.st_size - nb);
1.66 @@ -112,17 +143,47 @@
1.67 }
1.68 close(fd);
1.69
1.70 +#if HAVE_SYS_MMAN_H
1.71 + of->addr = addr;
1.72 + of->length = st.st_size;
1.73 +#endif
1.74 +
1.75 return addr;
1.76 }
1.77
1.78 int razor_file_free_contents(void *addr, size_t length)
1.79 {
1.80 #if HAVE_SYS_MMAN_H
1.81 - return munmap(addr, length);
1.82 -#else
1.83 + int retval, mmapped;
1.84 + struct open_file *of, *ofend;
1.85 +
1.86 + ofend = open_files.data + open_files.size;
1.87 + for (of = open_files.data; of < ofend; of++)
1.88 + if ((of->flags & OPEN_FILE_USED) && of->addr == addr)
1.89 + break;
1.90 +
1.91 + if (of == ofend)
1.92 + return 1;
1.93 +
1.94 + length = of->length;
1.95 + mmapped = of->flags & OPEN_FILE_MMAPPED;
1.96 + of->flags &= ~OPEN_FILE_USED;
1.97 +
1.98 + for (of = open_files.data; of < ofend; of++)
1.99 + if (of->flags & OPEN_FILE_USED)
1.100 + break;
1.101 +
1.102 + if (of == ofend) {
1.103 + array_release(&open_files);
1.104 + array_init(&open_files);
1.105 + }
1.106 +
1.107 + if (mmapped)
1.108 + return munmap(addr, length);
1.109 +#endif
1.110 +
1.111 free(addr);
1.112 return 0;
1.113 -#endif
1.114 }
1.115
1.116 struct qsort_context {