Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright  2013 Ran Benita <ran234 (at) gmail.com>
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  */
     23 
     24 #include "utils.h"
     25 
     26 #ifdef HAVE_MMAP
     27 
     28 #include <fcntl.h>
     29 #include <unistd.h>
     30 #include <sys/mman.h>
     31 #include <sys/stat.h>
     32 #include <sys/types.h>
     33 
     34 bool
     35 map_file(FILE *file, const char **string_out, size_t *size_out)
     36 {
     37     struct stat stat_buf;
     38     const int fd = fileno(file);
     39     char *string;
     40 
     41     /* Make sure to keep the errno on failure! */
     42 
     43     if (fstat(fd, &stat_buf) != 0)
     44         return false;
     45 
     46     string = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
     47     if (string == MAP_FAILED)
     48         return false;
     49 
     50     *string_out = string;
     51     *size_out = stat_buf.st_size;
     52     return true;
     53 }
     54 
     55 void
     56 unmap_file(const char *str, size_t size)
     57 {
     58     munmap(UNCONSTIFY(str), size);
     59 }
     60 
     61 #else
     62 
     63 bool
     64 map_file(FILE *file, const char **string_out, size_t *size_out)
     65 {
     66     long ret;
     67     size_t ret_s;
     68     char *string;
     69     size_t size;
     70 
     71     /* Make sure to keep the errno on failure! */
     72 
     73     ret = fseek(file, 0, SEEK_END);
     74     if (ret != 0)
     75         return false;
     76 
     77     ret = ftell(file);
     78     if (ret < 0)
     79         return false;
     80     size = (size_t) ret;
     81 
     82     ret = fseek(file, 0, SEEK_SET);
     83     if (ret < 0)
     84         return false;
     85 
     86     string = malloc(size);
     87     if (!string)
     88         return false;
     89 
     90     ret_s = fread(string, 1, size, file);
     91     if (ret_s < size) {
     92         free(string);
     93         return false;
     94     }
     95 
     96     *string_out = string;
     97     *size_out = size;
     98     return true;
     99 }
    100 
    101 void
    102 unmap_file(const char *str, size_t size)
    103 {
    104     free(UNCONSTIFY(str));
    105 }
    106 
    107 #endif
    108