git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] Replacing the system call pread() with real mmap().

From
SHStefan-W. Hahn <stefan.hahn@s-hahn.de>
Date
Jan 7, 2007, 11:17 UTC
Message-ID
<20070107111712.GB9909@scotty.home>
In-Reply-To
<20070107060007.GA10351@spearce.org>

Using cygwin with cygwin.dll before 1.5.22 the system call pread() is buggy. This patch introduces NO_PREAD. If NO_MMAP is not set and NO_PREAD is set git uses real mmap instead of pread.

Signed-off-by: Stefan-W. Hahn <stefan.hahn@s-hahn.de>
---
I made a patch for this problem replacing pread().
 Makefile          |    9 +++++++++
 compat/pread.c    |   16 ++++++++++++++++
 git-compat-util.h |    5 +++++
 3 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
index 180e1e0..4f928fd 100644
--- a/Makefile
+++ b/Makefile
@@ -69,6 +69,10 @@ all:
 #
 # Define NO_MMAP if you want to avoid mmap.
 #
+# Define NO_PREAD if you have a problem with pread() system call (i.e.
+# cygwin.dll before v1.5.22). This needs NO_MMAP not to be set, because pread()
+# is emulated using mmap.
+#
 # Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is
 # generally faster on your platform than accessing the working directory.
 #
@@ -521,6 +525,11 @@ endif
 ifdef NO_MMAP
 	COMPAT_CFLAGS += -DNO_MMAP
 	COMPAT_OBJS += compat/mmap.o
+else
+ifdef NO_PREAD
+	COMPAT_CFLAGS += -DNO_PREAD
+	COMPAT_OBJS += compat/pread.o
+endif
 endif
 ifdef NO_FAST_WORKING_DIRECTORY
 	BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY
diff --git a/compat/pread.c b/compat/pread.c
new file mode 100644
index 0000000..23e775d
--- /dev/null
+++ b/compat/pread.c
@@ -0,0 +1,16 @@
+#include "../git-compat-util.h"
+
+ssize_t git_pread(int fd,void *buf,size_t count,off_t offset)
+{
+        unsigned pg_offset = offset % getpagesize();
+        unsigned char *map;
+
+        map = mmap(NULL, count + pg_offset, PROT_READ, MAP_PRIVATE,
+                   fd, offset - pg_offset);
+        if (map == MAP_FAILED)
+                return -1;
+
+        memcpy(buf, map + pg_offset, count);
+        munmap(map, count + pg_offset);
+        return count;
+}
diff --git a/git-compat-util.h b/git-compat-util.h
index 5d9eb26..413e7e8 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -96,6 +96,11 @@ extern int git_munmap(void *start, size_t length);
 
 #include <sys/mman.h>
 
+#ifdef NO_PREAD
+#define pread git_pread
+extern ssize_t git_pread(int fd,void *buf,size_t count,off_t offset);
+#endif
+
 #endif /* NO_MMAP */
 
 #ifdef NO_SETENV
-- 
1.5.0.rc0.g244a7
Previous: Shawn O. PearceNext: Shawn O. Pearce
Message 4 of 12 in “problem with git clone on cygwin”
  1. Stefan-W. HahnJan 6, 2007
  2. Juergen RuehleJan 6, 2007
  3. Shawn O. PearceJan 7, 2007
  4. Replacing the system call pread() with real mmap().Stefan-W. Hahn, Jan 7, 2007
  5. Shawn O. PearceJan 7, 2007
  6. Stefan-W. HahnJan 7, 2007
  7. Johannes SchindelinJan 7, 2007
  8. Stefan-W. HahnJan 7, 2007
  9. Test for failing pread() on cygwin.Stefan-W. Hahn, Jan 7, 2007
  10. Stefan-W. HahnJan 7, 2007
  11. Juergen RuehleJan 7, 2007
  12. Stefan-W. HahnJan 7, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.