[PATCH] If NO_MMAP is defined, fake mmap() and munmap()
[git/jrn.git] / compat / mmap.c
blobfca6321ce01152c826bf977cd6b4d6b047ec57fa
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <errno.h>
5 #include "../cache.h"
7 typedef struct fakemmapwritable {
8 void *start;
9 size_t length;
10 int fd;
11 off_t offset;
12 struct fakemmapwritable *next;
13 } fakemmapwritable;
15 static fakemmapwritable *writablelist = NULL;
17 void *gitfakemmap(void *start, size_t length, int prot , int flags, int fd, off_t offset)
19 int n = 0;
21 if(start != NULL)
22 die("Invalid usage of gitfakemmap.");
24 if(lseek(fd, offset, SEEK_SET)<0) {
25 errno = EINVAL;
26 return MAP_FAILED;
29 start = xmalloc(length);
30 if(start == NULL) {
31 errno = ENOMEM;
32 return MAP_FAILED;
35 while(n < length) {
36 int count = read(fd, start+n, length-n);
38 if(count == 0) {
39 memset(start+n, 0, length-n);
40 break;
43 if(count < 0) {
44 free(start);
45 errno = EACCES;
46 return MAP_FAILED;
49 n += count;
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;
62 return start;
65 int gitfakemunmap(void *start, size_t length)
67 fakemmapwritable *writable = writablelist, *before = NULL;
69 while(writable && (writable->start > start + length
70 || writable->start + writable->length < start)) {
71 before = writable;
72 writable = writable->next;
75 if(writable) {
76 /* need to write back the contents */
77 int n = 0;
79 if(writable->start != start || writable->length != length)
80 die("fakemmap does not support partial write back.");
82 if(lseek(writable->fd, writable->offset, SEEK_SET) < 0) {
83 free(start);
84 errno = EBADF;
85 return -1;
88 while(n < length) {
89 int count = write(writable->fd, start + n, length - n);
91 if(count < 0) {
92 errno = EINVAL;
93 return -1;
96 n += count;
99 close(writable->fd);
101 if(before)
102 before->next = writable->next;
103 else
104 writablelist = writable->next;
106 free(writable);
109 free(start);
111 return 0;