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

Re: [PATCH 3/7] read_in_full: reset errno before reading

From
Jeff King <peff@peff.net>
Date
Sep 27, 2017, 04:07 UTC
Message-ID
<20170927040721.6av4o7cjrrkzizzo@sigill.intra.peff.net>
In-Reply-To
<xmqqvak6ayk0.fsf@gitster.mtv.corp.google.com>
On Tue, Sep 26, 2017 at 01:11:59PM +0900, Junio C Hamano wrote:
Show 16 quoted lines
> Jeff King <peff@peff.net> writes:
> 
> >> #ifndef EUNDERFLOW
> >> # ifdef ENODATA
> >> #  define EUNDERFLOW ENODATA
> >> # else
> >> #  define EUNDERFLOW ESPIPE
> >> # endif
> >> #endif
> >
> > Right, I think our mails just crossed but I'm leaning in this direction.
> 
> Hmph, I may be slow (or may be skimming the exchanges too fast), but
> what exactly is wrong with "0"?  As long as we do not have to tell
> two or more "not exactly an error from syscall in errno" cases, I
> would think "0" is the best value to use.

The main reason to avoid "0" is just that the "read error: Success" message is a bit funny.

Show 14 quoted lines
> If the syserror message _is_ the issue, then we'd need to either
> pick an existing errno that is available everywhere (with possibly
> suboptimal message), or pick something and prepare a fallback for
> platforms that lack the errno, so picking "0" as the value and use
> whatever logic we would have used for the "fallback" would not sound
> too bad.  I.e.
> 
> 	if (read_in_full(..., size) != size)
> 		if (errno)
> 			die_errno("oops");
> 		else
> 			die("short read");
> 
> If the callsite were too numerous,
You actually don't need errno for that. You can write:
  ret = read_in_full(..., size);
  if (ret < 0)
	die_errno("oops");
  else if (ret != size)
	die("short read");

So I think using errno as a sentinel value to tell between the two cases doesn't have much value.

> #define die_errno_or(msg1, msg2) if (errno) die_errno(msg1); else die(msg2)
> 
> perhaps?

If you just care about dying, you can wrap the whole read_in_full() in a helper (which is what my original patch 7 did). But I found there were cases that didn't want to die. Of course _most_ of those don't bother looking at errno in the first place. I think the only one that does is index_core(), which calls error_errno().

So with two helpers (one for die and one for error), I think we could cover the existing cases. Or we could convert the single error() case to just handle the logic inline.

One of the reasons I dislike the helper I showed earlier is that it involves assembling a lego sentence. But the alternative is requiring the caller to write both sentences from scratch (and writing a good sentence for the short read really is long: you expected X bytes but got Y).

I guess just tweaking the errno value does not really give a good "short read" error either. You get "unable to read foo: No data available", without the X/Y information.

Sometimes a custom "short read" message can be better, if it's "could not read enough bytes for packfile header" or similar. You don't need to know the exact number then.

So I dunno. Maybe I have just talked myself into actually just fixing all of the read_in_full() call sites manually.

-Peff
Previous: Junio C HamanoNext: Junio C Hamano
Message 22 of 51 in “read/write_in_full leftovers”
  1. 0/7 read/write_in_full leftoversJeff King, Sep 25, 2017
  2. 1/7 files-backend: prefer "0" for write_in_full() error checkJeff King, Sep 25, 2017
  3. Jonathan NiederSep 25, 2017
  4. Jeff KingSep 25, 2017
  5. 2/7 notes-merge: drop dead zero-write codeJeff King, Sep 25, 2017
  6. Jonathan NiederSep 25, 2017
  7. 3/7 read_in_full: reset errno before readingJeff King, Sep 25, 2017
  8. Jonathan NiederSep 25, 2017
  9. Jeff KingSep 25, 2017
  10. Jonathan NiederSep 25, 2017
  11. Jeff KingSep 25, 2017
  12. Jeff KingSep 25, 2017
  13. Jonathan NiederSep 25, 2017
  14. Jeff KingSep 26, 2017
  15. Stefan BellerSep 26, 2017
  16. Jeff KingSep 26, 2017
  17. Jonathan NiederSep 26, 2017
  18. Jonathan NiederSep 26, 2017
  19. Jeff KingSep 26, 2017
  20. Jonathan NiederSep 26, 2017
  21. Junio C HamanoSep 26, 2017
  22. Jeff KingSep 27, 2017
  23. Junio C HamanoSep 27, 2017
  24. Jonathan NiederSep 26, 2017
  25. Jeff KingSep 26, 2017
  26. Jonathan NiederSep 26, 2017
  27. Jeff KingSep 26, 2017
  28. Jonathan NiederSep 26, 2017
  29. Jonathan NiederSep 25, 2017
  30. 4/7 get-tar-commit-id: prefer "!=" for read_in_full() error checkJeff King, Sep 25, 2017
  31. Jonathan NiederSep 25, 2017
  32. 5/7 worktree: use xsize_t to access file sizeJeff King, Sep 25, 2017
  33. Jonathan NiederSep 25, 2017
  34. 6/7 worktree: check the result of read_in_full()Jeff King, Sep 25, 2017
  35. Jonathan NiederSep 25, 2017
  36. Jeff KingSep 25, 2017
  37. 7/7 add xread_in_full() helperJeff King, Sep 25, 2017
  38. Jonathan NiederSep 25, 2017
  39. Jeff KingSep 25, 2017
  40. 0/7 read/write_in_full leftoversJeff King, Sep 27, 2017
  41. 1/7 files-backend: prefer "0" for write_in_full() error checkJeff King, Sep 27, 2017
  42. 2/7 notes-merge: drop dead zero-write codeJeff King, Sep 27, 2017
  43. 3/7 prefer "!=" when checking read_in_full() resultJeff King, Sep 27, 2017
  44. Junio C HamanoSep 27, 2017
  45. Jeff KingSep 27, 2017
  46. 4/7 avoid looking at errno for short read_in_full() returnsJeff King, Sep 27, 2017
  47. Junio C HamanoSep 27, 2017
  48. 5/7 distinguish error versus short read from read_in_full()Jeff King, Sep 27, 2017
  49. 6/7 worktree: use xsize_t to access file sizeJeff King, Sep 27, 2017
  50. 7/7 worktree: check the result of read_in_full()Jeff King, Sep 27, 2017
  51. Junio C HamanoSep 27, 2017

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.