[Toybox] default SIGPIPE handler that calls _exit(0)?

Rich Felker dalias at libc.org
Mon Apr 27 09:34:55 PDT 2015


On Mon, Apr 27, 2015 at 09:26:11AM -0700, enh wrote:
> On Mon, Apr 27, 2015 at 9:22 AM, Rich Felker <dalias at libc.org> wrote:
> > On Mon, Apr 27, 2015 at 09:17:31AM -0700, enh wrote:
> >> On Mon, Apr 27, 2015 at 9:11 AM, Rich Felker <dalias at libc.org> wrote:
> >> > On Mon, Apr 27, 2015 at 08:36:53AM -0700, enh wrote:
> >> >> On Sun, Apr 26, 2015 at 7:30 PM, Rich Felker <dalias at libc.org> wrote:
> >> >> > On Sat, Apr 25, 2015 at 12:14:44PM -0700, enh wrote:
> >> >> >> what's the plan wrt SIGPIPE? the desktop is pretty inconsistent. many
> >> >> >> (but not all) commands install a signal handler that does _exit(0).
> >> >> >> others (coreutils 8.21's ls, say) do nothing. normally "what you do
> >> >> >> about SIGPIPE" isn't a problem but on Android that leads to a crash
> >> >> >> report and people filing "ls crashed" bugs against me. (our default
> >> >> >> shell PS setup is also noisy about crashes.)
> >> >> >
> >> >> > Why not just *block* SIGPIPE (with sigprocmask) so that the write
> >> >> > returns an error (EPIPE) and the program applies the same logic it
> >> >> > would for any other write error?
> >> >>
> >> >> toybox does a little better than toolbox there thanks to xwrite, but
> >> >> i've yet never met anyone who checks the return value of printf...
> >> >>
> >> >> plus there's the question of whether giving up because you're writing
> >> >> to a broken pipe is an error exit or not. you could add a special case
> >> >> to xwrite (and add xprintf and xputs and...), but since the whole idea
> >> >> is that code shouldn't have to care, it's easier just to install a
> >> >> signal handler that does _exit(0).
> >> >
> >> > _exit(0) is wrong and broken. It reports success when the command did
> >> > not succeed.
> >>
> >> coreutils seems divided on this issue.
> >
> > Could you provide some examples? I think POSIX is pretty clear that
> > you can't return success if the output was not successfully written.
> > As I already mentioned doing so results in data loss. I really doubt
> > coreutils is doing this, but well, GNU software is not always a good
> > example of doing the Right Thing...
> 
> i did in my original mail.

OK, I'll look back to it.

> >> > Failure of the caller to recognize that it didn't succeed
> >> > can result in data loss. If anything the right behavior for the signal
> >> > handler would be _exit(1) not _exit(0). But I think xwrite/xprintf
> >> > solves the issue more elegantly. Note that even if you don't check
> >> > every printf, you still get the error status from ferror and/or fflush
> >> > at close time (if you check them) but that might result in a lot of
> >> > wasted cpu time if you continue processing/writing after a pipe broke.
> >>
> >> it would also result in things like top(1) not exiting.
> >
> > If top is using stdio, it's easy to add a single ferror(stdout) check
> > to the main loop. If it's using write(), it _must_ be checking for
> > errors anyway since write can always return with a short/partial
> > write. But top is unlikely to be hooked up to a pipe or socket anyway;
> > it normally needs a terminal.
> 
> the point is that then people need to think. if that were a plausible
> solution, this thread wouldn't exist. the advantage of the signal
> handler is that humans can keep on being humans.

Either way people need to think; otherwise you have a bug where write
failure is not being reported and data loss results. You won't have
that from EPIPE if you use the signal handler, but you'll instead have
it from ENOSPC (at the very least, and perhaps others). The main flow
of execution _NEEDS_ to check for write errors. If you can't trust
people to do this locally, just have a policy of using xwrite,
xprintf, etc.

Rich

 1430152495.0


More information about the Toybox mailing list