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

[PATCH] read_in_full: always report errors

From
Jeff King <peff@peff.net>
Date
May 26, 2011, 16:30 UTC
Message-ID
<20110526163027.GC4049@sigill.intra.peff.net>
In-Reply-To
<87hb8h5y09.fsf@rho.meyering.net>
On Thu, May 26, 2011 at 04:37:10PM +0200, Jim Meyering wrote:
Show 18 quoted lines
> > It looks like if we get -1 on the _first_ read, we will then return -1.
> > Subsequent errors are then ignored, and we return the (possibly
> > truncated) result.
> >
> > Which, to be honest, seems kind of insane to me. I'd think:
> >
> >   while (count > 0) {
> >           ssize_t loaded = xread(fd, p, count);
> >           if (loaded < 0)
> >                   return loaded;
> >           if (loaded == 0)
> >                   return total;
> >           ...
> >   }
> >
> > would be much more sensible semantics.
> 
> That looks better to me, too.

I was worried that some caller might care about the truncated output, but after looking through the code, that is not the case. So I think we should do this.

-- >8 --
Subject: [PATCH] read_in_full: always report errors

The read_in_full function repeatedly calls read() to fill a buffer. If the first read() returns an error, we notify the caller by returning the error. However, if we read some data and then get an error on a subsequent read, we simply return the amount of data that we did read, and the caller is unaware of the error.

This makes the tradeoff that seeing the partial data is more important than the fact that an error occurred. In practice, this is generally not the case; we care more if an error occurred, and should throw away any partial data.

I audited the current callers. In most cases, this will make no difference at all, as they do:

  if (read_in_full(fd, buf, size) != size)
	  error("short read");
However, it will help in a few cases:
  1. In sha1_file.c:index_stream, we would fail to notice
     errors in the incoming stream.
  2. When reading symbolic refs in resolve_ref, we would
     fail to notice errors and potentially use a truncated
     ref name.
  3. In various places, we will get much better error
     messages. For example, callers of safe_read would
     erroneously print "the remote end hung up unexpectedly"
     instead of showing the read error.
Signed-off-by: Jeff King <peff@peff.net>
---
 wrapper.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/wrapper.c b/wrapper.c
index 2829000..85f09df 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -148,8 +148,10 @@ ssize_t read_in_full(int fd, void *buf, size_t count)
 
 	while (count > 0) {
 		ssize_t loaded = xread(fd, p, count);
-		if (loaded <= 0)
-			return total ? total : loaded;
+		if (loaded < 0)
+			return -1;
+		if (loaded == 0)
+			return total;
 		count -= loaded;
 		p += loaded;
 		total += loaded;
-- 
1.7.4.5.13.gd3ff5
Previous: Jim MeyeringNext: Junio C Hamano
Message 6 of 10 in “remove unnecessary test and dead diagnostic”
  1. remove unnecessary test and dead diagnosticJim Meyering, May 26, 2011
  2. Jeff KingMay 26, 2011
  3. Jim MeyeringMay 26, 2011
  4. Jeff KingMay 26, 2011
  5. Jim MeyeringMay 26, 2011
  6. read_in_full: always report errorsJeff King, May 26, 2011
  7. Junio C HamanoMay 26, 2011
  8. Jeff KingMay 26, 2011
  9. Junio C HamanoMay 26, 2011
  10. Jeff KingMay 26, 2011

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.