compat / mmap.con commit [PATCH] If NO_MMAP is defined, fake mmap() and munmap() (730d48a)
   1#include <stdio.h>
   2#include <stdlib.h>
   3#include <unistd.h>
   4#include <errno.h>
   5#include "../cache.h"
   6
   7typedef struct fakemmapwritable {
   8        void *start;
   9        size_t length;
  10        int fd;
  11        off_t offset;
  12        struct fakemmapwritable *next;
  13} fakemmapwritable;
  14
  15static fakemmapwritable *writablelist = NULL;
  16
  17void *gitfakemmap(void *start, size_t length, int prot , int flags, int fd, off_t offset)
  18{
  19        int n = 0;
  20
  21        if(start != NULL)
  22                die("Invalid usage of gitfakemmap.");
  23
  24        if(lseek(fd, offset, SEEK_SET)<0) {
  25                errno = EINVAL;
  26                return MAP_FAILED;
  27        }
  28
  29        start = xmalloc(length);
  30        if(start == NULL) {
  31                errno = ENOMEM;
  32                return MAP_FAILED;
  33        }
  34
  35        while(n < length) {
  36                int count = read(fd, start+n, length-n);
  37
  38                if(count == 0) {
  39                        memset(start+n, 0, length-n);
  40                        break;
  41                }
  42
  43                if(count < 0) {
  44                        free(start);
  45                        errno = EACCES;
  46                        return MAP_FAILED;
  47                }
  48
  49                n += count;
  50        }
  51
  52        if(prot & PROT_WRITE) {
  53                fakemmapwritable *next = xmalloc(sizeof(fakemmapwritable));
  54                next->start = start;
  55                next->length = length;
  56                next->fd = dup(fd);
  57                next->offset = offset;
  58                next->next = writablelist;
  59                writablelist = next;
  60        }
  61
  62        return start;
  63}
  64
  65int gitfakemunmap(void *start, size_t length)
  66{
  67        fakemmapwritable *writable = writablelist, *before = NULL;
  68
  69        while(writable && (writable->start > start + length
  70                        || writable->start + writable->length < start)) {
  71                before = writable;
  72                writable = writable->next;
  73        }
  74
  75        if(writable) {
  76                /* need to write back the contents */
  77                int n = 0;
  78
  79                if(writable->start != start || writable->length != length)
  80                        die("fakemmap does not support partial write back.");
  81
  82                if(lseek(writable->fd, writable->offset, SEEK_SET) < 0) {
  83                        free(start);
  84                        errno = EBADF;
  85                        return -1;
  86                }
  87
  88                while(n < length) {
  89                        int count = write(writable->fd, start + n, length - n);
  90
  91                        if(count < 0) {
  92                                errno = EINVAL;
  93                                return -1;
  94                        }
  95
  96                        n += count;
  97                }
  98
  99                close(writable->fd);
 100
 101                if(before)
 102                        before->next = writable->next;
 103                else
 104                        writablelist = writable->next;
 105
 106                free(writable);
 107        }
 108
 109        free(start);
 110
 111        return 0;
 112}
 113