Skip to content

Commit 730d48a

Browse files
dschoJunio C Hamano
authored andcommitted
[PATCH] If NO_MMAP is defined, fake mmap() and munmap()
Since some platforms do not support mmap() at all, and others do only just so, this patch introduces the option to fake mmap() and munmap() by malloc()ing and read()ing explicitely. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent d119e3d commit 730d48a

File tree

4 files changed

+135
-1
lines changed

4 files changed

+135
-1
lines changed

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
2828
# Patrick Mauritz).
2929
#
30+
# Define NO_MMAP if you want to avoid mmap.
31+
#
3032
# Define WITH_OWN_SUBPROCESS_PY if you want to use with python 2.3.
3133
#
3234
# Define NO_IPV6 if you lack IPv6 support and getaddrinfo().
@@ -258,6 +260,10 @@ ifdef NO_STRCASESTR
258260
DEFINES += -Dstrcasestr=gitstrcasestr
259261
LIB_OBJS += compat/strcasestr.o
260262
endif
263+
ifdef NO_MMAP
264+
DEFINES += -Dmmap=gitfakemmap -Dmunmap=gitfakemunmap -DNO_MMAP
265+
LIB_OBJS += compat/mmap.o
266+
endif
261267
ifdef NO_IPV6
262268
DEFINES += -DNO_IPV6 -Dsockaddr_storage=sockaddr_in
263269
endif

cache.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
#include <string.h>
1212
#include <errno.h>
1313
#include <limits.h>
14+
#ifndef NO_MMAP
1415
#include <sys/mman.h>
16+
#endif
1517
#include <sys/param.h>
1618
#include <netinet/in.h>
1719
#include <sys/types.h>
@@ -356,4 +358,18 @@ extern void packed_object_info_detail(struct pack_entry *, char *, unsigned long
356358
/* Dumb servers support */
357359
extern int update_server_info(int);
358360

361+
#ifdef NO_MMAP
362+
363+
#ifndef PROT_READ
364+
#define PROT_READ 1
365+
#define PROT_WRITE 2
366+
#define MAP_PRIVATE 1
367+
#define MAP_FAILED ((void*)-1)
368+
#endif
369+
370+
extern void *gitfakemmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);
371+
extern int gitfakemunmap(void *start, size_t length);
372+
373+
#endif
374+
359375
#endif /* CACHE_H */

compat/mmap.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
#include <errno.h>
5+
#include "../cache.h"
6+
7+
typedef struct fakemmapwritable {
8+
void *start;
9+
size_t length;
10+
int fd;
11+
off_t offset;
12+
struct fakemmapwritable *next;
13+
} fakemmapwritable;
14+
15+
static fakemmapwritable *writablelist = NULL;
16+
17+
void *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+
65+
int 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+

mailsplit.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include <fcntl.h>
1010
#include <sys/types.h>
1111
#include <sys/stat.h>
12-
#include <sys/mman.h>
1312
#include <string.h>
1413
#include <stdio.h>
1514
#include <ctype.h>

0 commit comments

Comments
 (0)