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

Re: [PATCH v8 1/2] Add xpread()

From
Junio C Hamano <gitster@pobox.com>
Date
Apr 10, 2014, 19:20 UTC
Message-ID
<xmqqtxa1vvms.fsf@gitster.dls.corp.google.com>
In-Reply-To
<5346ED16.3050607@kdbg.org>
Johannes Sixt <j6t@kdbg.org> writes:
Show 10 quoted lines
> Am 10.04.2014 20:54, schrieb Yiannis Marangos:
>> +ssize_t xpread(int fd, void *buf, size_t len, off_t offset)
>> +{
>> +	ssize_t nr;
>> +	if (len > MAX_IO_SIZE)
>> +	    len = MAX_IO_SIZE;
>
> Odd indentation here.
>
> -- Hannes

Good eyes, even though this is copy&pasting an existing error from surrounding code ;-)

I'll queue this instead (rebased on top of maint-1.8.5 even though I doubt we would be issuing 1.8.5.6).

-- >8 --
From: Yiannis Marangos <yiannis.marangos@gmail.com>
Date: Thu, 10 Apr 2014 21:54:12 +0300
Subject: [PATCH] wrapper.c: add xpread() similar to xread()

It is a common mistake to call read(2)/pread(2) and forget to anticipate that they may return error with EAGAIN/EINTR when the system call is interrupted.

We have xread() helper to relieve callers of read(2) from having to worry about it; add xpread() helper to do the same for pread(2).

Update the caller in the builtin/index-pack.c and the mmap emulation in compat/.

Signed-off-by: Yiannis Marangos <yiannis.marangos@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/index-pack.c |  2 +-
 compat/mmap.c        |  4 +---
 git-compat-util.h    |  1 +
 wrapper.c            | 18 ++++++++++++++++++
 4 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 9e9eb4b..e7a6b53 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -542,7 +542,7 @@ static void *unpack_data(struct object_entry *obj,
 
 	do {
 		ssize_t n = (len < 64*1024) ? len : 64*1024;
-		n = pread(pack_fd, inbuf, n, from);
+		n = xpread(pack_fd, inbuf, n, from);
 		if (n < 0)
 			die_errno(_("cannot pread pack file"));
 		if (!n)
diff --git a/compat/mmap.c b/compat/mmap.c
index c9d46d1..7f662fe 100644
--- a/compat/mmap.c
+++ b/compat/mmap.c
@@ -14,7 +14,7 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t of
 	}
 
 	while (n < length) {
-		ssize_t count = pread(fd, (char *)start + n, length - n, offset + n);
+		ssize_t count = xpread(fd, (char *)start + n, length - n, offset + n);
 
 		if (count == 0) {
 			memset((char *)start+n, 0, length-n);
@@ -22,8 +22,6 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t of
 		}
 
 		if (count < 0) {
-			if (errno == EAGAIN || errno == EINTR)
-				continue;
 			free(start);
 			errno = EACCES;
 			return MAP_FAILED;
diff --git a/git-compat-util.h b/git-compat-util.h
index 7776f12..9eec5fb 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -534,6 +534,7 @@ extern void *xcalloc(size_t nmemb, size_t size);
 extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
 extern ssize_t xread(int fd, void *buf, size_t len);
 extern ssize_t xwrite(int fd, const void *buf, size_t len);
+extern ssize_t xpread(int fd, void *buf, size_t len, off_t offset);
 extern int xdup(int fd);
 extern FILE *xfdopen(int fd, const char *mode);
 extern int xmkstemp(char *template);
diff --git a/wrapper.c b/wrapper.c
index 0cc5636..5b3c7fc 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -174,6 +174,24 @@ ssize_t xwrite(int fd, const void *buf, size_t len)
 	}
 }
 
+/*
+ * xpread() is the same as pread(), but it automatically restarts pread()
+ * operations with a recoverable error (EAGAIN and EINTR). xpread() DOES
+ * NOT GUARANTEE that "len" bytes is read even if the data is available.
+ */
+ssize_t xpread(int fd, void *buf, size_t len, off_t offset)
+{
+	ssize_t nr;
+	if (len > MAX_IO_SIZE)
+		len = MAX_IO_SIZE;
+	while (1) {
+		nr = pread(fd, buf, len, offset);
+		if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
+			continue;
+		return nr;
+	}
+}
+
 ssize_t read_in_full(int fd, void *buf, size_t count)
 {
 	char *p = buf;
-- 
1.9.2-590-g468068b
Previous: Johannes Sixt
Message 31 of 31 in “Verify index file before we opportunistically update it”
  1. Verify index file before we opportunistically update itYiannis Marangos, Apr 9, 2014
  2. Verify index file before we opportunistically update itYiannis Marangos, Apr 9, 2014
  3. Verify index file before we opportunistically update itYiannis Marangos, Apr 9, 2014
  4. Junio C HamanoApr 9, 2014
  5. Verify index file before we opportunistically update itYiannis Marangos, Apr 9, 2014
  6. Verify index file before we opportunistically update itYiannis Marangos, Apr 10, 2014
  7. Verify index file before we opportunistically update itYiannis Marangos, Apr 10, 2014
  8. Duy NguyenApr 10, 2014
  9. Yiannis MarangosApr 10, 2014
  10. Junio C HamanoApr 10, 2014
  11. Verify index file before we opportunistically update itYiannis Marangos, Apr 10, 2014
  12. 1/2 Add xpread() and xpwrite()Yiannis Marangos, Apr 10, 2014
  13. 2/2 Verify index file before we opportunistically update itYiannis Marangos, Apr 10, 2014
  14. Junio C HamanoApr 10, 2014
  15. Duy NguyenApr 11, 2014
  16. Junio C HamanoApr 11, 2014
  17. Junio C HamanoApr 11, 2014
  18. Yiannis MarangosApr 11, 2014
  19. Duy NguyenApr 12, 2014
  20. Junio C HamanoApr 12, 2014
  21. Junio C HamanoApr 12, 2014
  22. Duy NguyenApr 12, 2014
  23. Junio C HamanoApr 14, 2014
  24. Torsten BögershausenApr 11, 2014
  25. Yiannis MarangosApr 11, 2014
  26. Duy NguyenApr 11, 2014
  27. Junio C HamanoApr 10, 2014
  28. Yiannis MarangosApr 10, 2014
  29. 1/2 Add xpread()Yiannis Marangos, Apr 10, 2014
  30. Johannes SixtApr 10, 2014
  31. Junio C HamanoApr 10, 2014

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.