{"thread":{"id":"2045","subject":"[PATCH] If NO_MMAP is defined, fake mmap() and munmap()","startedAt":"2005-10-07T22:55:40Z","lastAt":"2005-10-07T23:57:35Z","messageCount":3,"participants":["Johannes Schindelin","Junio C Hamano","Alex Riesen"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"9817","messageId":"Pine.LNX.4.63.0510080050550.20922@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2045","inReplyTo":null,"subject":"[PATCH] If NO_MMAP is defined, fake mmap() and munmap()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-10-07T22:55:40Z","receivedAt":"2005-10-07T22:55:40Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nSince some platforms do not support mmap() at all, and others do only just \nso, this patch introduces the option to fake mmap() and munmap() by \nmalloc()ing and read()ing explicitely.\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\n---\n\nOnly lightly tested, but it seems to work correctly (after all, this \ncommit was created after compiling with NO_MMAP=1).\n\n Makefile      |    6 +++\n cache.h       |   16 ++++++++\n compat/mmap.c |  113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n mailsplit.c   |    1 -\n 4 files changed, 135 insertions(+), 1 deletions(-)\n create mode 100644 compat/mmap.c\n\napplies-to: 2c165e1b55bf857247c0f074e9bea680bf411586\n3d4f1e103b35c28c8190f9a59ffa95221277fdb4\ndiff --git a/Makefile b/Makefile\nindex 2f7cdd4..fb4c410 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -27,6 +27,8 @@\n # Define NEEDS_SOCKET if linking with libc is not enough (SunOS,\n # Patrick Mauritz).\n #\n+# Define NO_MMAP if you want to avoid mmap.\n+#\n # Define WITH_OWN_SUBPROCESS_PY if you want to use with python 2.3.\n #\n # Define NO_IPV6 if you lack IPv6 support and getaddrinfo().\n@@ -259,6 +261,10 @@ ifdef NO_STRCASESTR\n \tDEFINES += -Dstrcasestr=gitstrcasestr\n \tLIB_OBJS += compat/strcasestr.o\n endif\n+ifdef NO_MMAP\n+\tDEFINES += -Dmmap=gitfakemmap -Dmunmap=gitfakemunmap -DNO_MMAP\n+\tLIB_OBJS += compat/mmap.o\n+endif\n ifdef NO_IPV6\n \tDEFINES += -DNO_IPV6 -Dsockaddr_storage=sockaddr_in\n endif\ndiff --git a/cache.h b/cache.h\nindex 514adb8..5987d4c 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -11,7 +11,9 @@\n #include <string.h>\n #include <errno.h>\n #include <limits.h>\n+#ifndef NO_MMAP\n #include <sys/mman.h>\n+#endif\n #include <sys/param.h>\n #include <netinet/in.h>\n #include <sys/types.h>\n@@ -356,4 +358,18 @@ extern void packed_object_info_detail(st\n /* Dumb servers support */\n extern int update_server_info(int);\n \n+#ifdef NO_MMAP\n+\n+#ifndef PROT_READ\n+#define PROT_READ 1\n+#define PROT_WRITE 2\n+#define MAP_PRIVATE 1\n+#define MAP_FAILED ((void*)-1)\n+#endif\n+\n+extern void *gitfakemmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);\n+extern int gitfakemunmap(void *start, size_t length);\n+\n+#endif\n+\n #endif /* CACHE_H */\ndiff --git a/compat/mmap.c b/compat/mmap.c\nnew file mode 100644\nindex 0000000..fca6321\n--- /dev/null\n+++ b/compat/mmap.c\n@@ -0,0 +1,113 @@\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <unistd.h>\n+#include <errno.h>\n+#include \"../cache.h\"\n+\n+typedef struct fakemmapwritable {\n+\tvoid *start;\n+\tsize_t length;\n+\tint fd;\n+\toff_t offset;\n+\tstruct fakemmapwritable *next;\n+} fakemmapwritable;\n+\n+static fakemmapwritable *writablelist = NULL;\n+\n+void *gitfakemmap(void *start, size_t length, int prot , int flags, int fd, off_t offset)\n+{\n+\tint n = 0;\n+\n+\tif(start != NULL)\n+\t\tdie(\"Invalid usage of gitfakemmap.\");\n+\n+\tif(lseek(fd, offset, SEEK_SET)<0) {\n+\t\terrno = EINVAL;\n+\t\treturn MAP_FAILED;\n+\t}\n+\n+\tstart = xmalloc(length);\n+\tif(start == NULL) {\n+\t\terrno = ENOMEM;\n+\t\treturn MAP_FAILED;\n+\t}\n+\n+\twhile(n < length) {\n+\t\tint count = read(fd, start+n, length-n);\n+\n+\t\tif(count == 0) {\n+\t\t\tmemset(start+n, 0, length-n);\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tif(count < 0) {\n+\t\t\tfree(start);\n+\t\t\terrno = EACCES;\n+\t\t\treturn MAP_FAILED;\n+\t\t}\n+\n+\t\tn += count;\n+\t}\n+\n+\tif(prot & PROT_WRITE) {\n+\t\tfakemmapwritable *next = xmalloc(sizeof(fakemmapwritable));\n+\t\tnext->start = start;\n+\t\tnext->length = length;\n+\t\tnext->fd = dup(fd);\n+\t\tnext->offset = offset;\n+\t\tnext->next = writablelist;\n+\t\twritablelist = next;\n+\t}\n+\n+\treturn start;\n+}\n+\n+int gitfakemunmap(void *start, size_t length)\n+{\n+\tfakemmapwritable *writable = writablelist, *before = NULL;\n+\n+\twhile(writable && (writable->start > start + length\n+\t\t\t|| writable->start + writable->length < start)) {\n+\t\tbefore = writable;\n+\t\twritable = writable->next;\n+\t}\n+\n+\tif(writable) {\n+\t\t/* need to write back the contents */\n+\t\tint n = 0;\n+\n+\t\tif(writable->start != start || writable->length != length)\n+\t\t\tdie(\"fakemmap does not support partial write back.\");\n+\n+\t\tif(lseek(writable->fd, writable->offset, SEEK_SET) < 0) {\n+\t\t\tfree(start);\n+\t\t\terrno = EBADF;\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\twhile(n < length) {\n+\t\t\tint count = write(writable->fd, start + n, length - n);\n+\n+\t\t\tif(count < 0) {\n+\t\t\t\terrno = EINVAL;\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\n+\t\t\tn += count;\n+\t\t}\n+\n+\t\tclose(writable->fd);\n+\n+\t\tif(before)\n+\t\t\tbefore->next = writable->next;\n+\t\telse\n+\t\t\twritablelist = writable->next;\n+\n+\t\tfree(writable);\n+\t}\n+\n+\tfree(start);\n+\n+\treturn 0;\n+}\n+\ndiff --git a/mailsplit.c b/mailsplit.c\nindex 7981f87..0f8100d 100644\n--- a/mailsplit.c\n+++ b/mailsplit.c\n@@ -9,7 +9,6 @@\n #include <fcntl.h>\n #include <sys/types.h>\n #include <sys/stat.h>\n-#include <sys/mman.h>\n #include <string.h>\n #include <stdio.h>\n #include <ctype.h>\n---\n0.99.8.GIT\n"},{"id":"9821","messageId":"7vwtkoyjs9.fsf@assigned-by-dhcp.cox.net","threadId":"2045","inReplyTo":"Pine.LNX.4.63.0510080050550.20922@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] If NO_MMAP is defined, fake mmap() and munmap()","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-10-07T23:44:22Z","receivedAt":"2005-10-07T23:44:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Since some platforms do not support mmap() at all, and others do only just \n> so, this patch introduces the option to fake mmap() and munmap() by \n> malloc()ing and read()ing explicitely.\n\nI guess I can just drop Alex Riesen patch and any other recent\npatches that try to work around mmap().  Happy!\n\n \n"},{"id":"9825","messageId":"20051007235735.GB14827@steel.home","threadId":"2045","inReplyTo":"7vwtkoyjs9.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] If NO_MMAP is defined, fake mmap() and munmap()","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2005-10-07T23:57:35Z","receivedAt":"2005-10-07T23:57:35Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Junio C Hamano, Sat, Oct 08, 2005 01:44:22 +0200:\n> > Since some platforms do not support mmap() at all, and others do only just \n> > so, this patch introduces the option to fake mmap() and munmap() by \n> > malloc()ing and read()ing explicitely.\n> \n> I guess I can just drop Alex Riesen patch and any other recent\n> patches that try to work around mmap().  Happy!\n> \n\nMe too. I was just about to make a read_cache read the whole index in\n(absolutely the same as Johannes, but not that elegant).\n\nThe platform(s) deserve such a treatment :)\n"}]}