Merge branch 'lt/revision-walker'
[gitweb.git] / compat / mmap.c
index fca6321ce01152c826bf977cd6b4d6b047ec57fa..c9d46d174259f42a3e2a2eb073475aba517044be 100644 (file)
@@ -1,46 +1,29 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include "../cache.h"
+#include "../git-compat-util.h"
 
-typedef struct fakemmapwritable {
-       void *start;
-       size_t length;
-       int fd;
-       off_t offset;
-       struct fakemmapwritable *next;
-} fakemmapwritable;
-
-static fakemmapwritable *writablelist = NULL;
-
-void *gitfakemmap(void *start, size_t length, int prot , int flags, int fd, off_t offset)
+void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
 {
-       int n = 0;
+       size_t n = 0;
 
-       if(start != NULL)
-               die("Invalid usage of gitfakemmap.");
-
-       if(lseek(fd, offset, SEEK_SET)<0) {
-               errno = EINVAL;
-               return MAP_FAILED;
-       }
+       if (start != NULL || !(flags & MAP_PRIVATE))
+               die("Invalid usage of mmap when built with NO_MMAP");
 
        start = xmalloc(length);
-       if(start == NULL) {
+       if (start == NULL) {
                errno = ENOMEM;
                return MAP_FAILED;
        }
 
-       while(n < length) {
-               int count = read(fd, start+n, length-n);
+       while (n < length) {
+               ssize_t count = pread(fd, (char *)start + n, length - n, offset + n);
 
-               if(count == 0) {
-                       memset(start+n, 0, length-n);
+               if (count == 0) {
+                       memset((char *)start+n, 0, length-n);
                        break;
                }
 
-               if(count < 0) {
+               if (count < 0) {
+                       if (errno == EAGAIN || errno == EINTR)
+                               continue;
                        free(start);
                        errno = EACCES;
                        return MAP_FAILED;
@@ -49,65 +32,11 @@ void *gitfakemmap(void *start, size_t length, int prot , int flags, int fd, off_
                n += count;
        }
 
-       if(prot & PROT_WRITE) {
-               fakemmapwritable *next = xmalloc(sizeof(fakemmapwritable));
-               next->start = start;
-               next->length = length;
-               next->fd = dup(fd);
-               next->offset = offset;
-               next->next = writablelist;
-               writablelist = next;
-       }
-
        return start;
 }
 
-int gitfakemunmap(void *start, size_t length)
+int git_munmap(void *start, size_t length)
 {
-       fakemmapwritable *writable = writablelist, *before = NULL;
-
-       while(writable && (writable->start > start + length
-                       || writable->start + writable->length < start)) {
-               before = writable;
-               writable = writable->next;
-       }
-
-       if(writable) {
-               /* need to write back the contents */
-               int n = 0;
-
-               if(writable->start != start || writable->length != length)
-                       die("fakemmap does not support partial write back.");
-
-               if(lseek(writable->fd, writable->offset, SEEK_SET) < 0) {
-                       free(start);
-                       errno = EBADF;
-                       return -1;
-               }
-
-               while(n < length) {
-                       int count = write(writable->fd, start + n, length - n);
-
-                       if(count < 0) {
-                               errno = EINVAL;
-                               return -1;
-                       }
-
-                       n += count;
-               }
-
-               close(writable->fd);
-
-               if(before)
-                       before->next = writable->next;
-               else
-                       writablelist = writable->next;
-
-               free(writable);
-       }
-
        free(start);
-
        return 0;
 }
-