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

Re: [PATCH 2/2] Check for IO errors after running a command

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
Jun 25, 2007, 15:57 UTC
Message-ID
<alpine.LFD.0.98.0706250837550.3593@woody.linux-foundation.org>
In-Reply-To
<877ipsw2sz.fsf@rho.meyering.net>
On Mon, 25 Jun 2007, Jim Meyering wrote:
> 
> That has the disadvantage of ignoring *all* pipe and socket write errors.
.. which is the only wayt to do it.
There's *no*way* to tell what the error was for the case of
	if (ferror(stdout))
		..
because the original errno has long long since been thrown away.
> Of course, one can probably argue that those are all unlikely.
> They may be even less likely than an actual EPIPE, but the point is
> that people and tools using git plumbing should be able to rely on
> it to report such write failures, no matter how unusual they are.

..but since what you suggest is physically impossible in a half-way portable manner, and since all relevant such errors are likely to have happened long before, I would suggest:

 - Use my patch
OR
 - Stop using stdio. 
   You *cannot* make stdio error handling sane. It's simply not possible. 
   The whole point of stdio is to simplify things, but it does so to the 
   point where portable and reliable error handling is not an option any 
   more.
   Replace all command output that you care about with some stdio 
   replacement. We do that for all the paths we *really* care about, where 
   we use raw unistd IO and do our own buffering (ie things like the 
   "write_in_full()" stuff and "write_sha1_file()" etc.

Anybody who thinks he can handle errors with stdio is simply barking up the wrogn tree. It can be done, but it can be done only by essentially making stdio be a really awkward way to do IO, and you're better off with the raw unistd.h interfaces.

In particular, you need to make sure you check *each* return value of every single stdio operation. Even then, you don't actually know if "errno" is set correctly if an error happens in the middle (ie most stdio routines are just defined to return EOF or nonzero on error, and it's not at all clear that errno is reliable).

If you don't, a buffer flush error may have happened at any time, and whatever error code it had has been thrown away, and turned into one single bit (the "ferror()" thing).

And yes, some libc's might have extensions that actually guarantee more. But even then I would be *very* surprised if they actually work and have been tested to any real degree (glibc does not. The stream error is a single bit. I checked)

So really: if you care about a particular read or write, use the "write_in_full()" and "read_in_full()" functions. NOTHING ELSE!

			Linus
Previous: Jim MeyeringNext: Matthias Lederhofer
Message 10 of 13 in “(resend) [PATCH] Don't ignore write failure from git-diff, git-log, etc.”
  1. Jim MeyeringJun 23, 2007
  2. Junio C HamanoJun 24, 2007
  3. Linus TorvaldsJun 24, 2007
  4. 1/2 Clean up internal command handlingLinus Torvalds, Jun 24, 2007
  5. 2/2 Check for IO errors after running a commandLinus Torvalds, Jun 24, 2007
  6. Junio C HamanoJun 25, 2007
  7. Johannes SchindelinJun 25, 2007
  8. Johannes SixtJun 25, 2007
  9. Jim MeyeringJun 25, 2007
  10. Linus TorvaldsJun 25, 2007
  11. Matthias LederhoferJun 26, 2007
  12. Jim MeyeringJun 25, 2007
  13. Jim MeyeringJun 24, 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.