librazor/util.c
changeset 461 e1b95d57dd54
parent 455 df914f383f5c
child 475 008c75a5e08d
     1.1 --- a/librazor/util.c	Thu Oct 09 17:27:41 2014 +0100
     1.2 +++ b/librazor/util.c	Tue Nov 11 15:57:14 2014 +0000
     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 {