[adding coreutils] On 02/07/2012 11:21 PM, Paul Eggert wrote: > On 01/20/2012 11:06 PM, Paul Eggert wrote: >> I took a look and came up with four related patches to fix these. >> Here's the first one. It fixes the originally-reported bug. > > I found a problem in that patch's test case: it assumes > that SIGPIPE has the default action when the test is > run, which isn't a portable assumption. I installed the > following further patch to fix this bug in the test case.
Alas, you _cannot_ use trap to undo a shell that is started with SIGPIPE ignored. POSIX requires that: "Signals that were ignored on entry to a non-interactive shell cannot be trapped or reset, although no error need be reported when attempting to do so." http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#trap $ (trap '' PIPE; bash -c 'trap; trap - PIPE; trap') trap -- '' SIGPIPE trap -- '' SIGPIPE Even more interesting, ksh refuses to tell you that it is ignoring a trap, until you try to change it: $ (trap '' PIPE; ksh -c 'trap; echo 0; trap "echo 1" PIPE; trap; \ echo 2; kill -s PIPE $$; trap; echo 3') 0 trap -- '' PIPE 2 trap -- '' PIPE 3 Then there is dash, which obeys POSIX on ignoring changes to the trap, but fails to inform you (I'm filing a bug against dash, as that is just outright mean to lie): $ (trap '' PIPE; dash -c 'trap; echo 0; trap "echo 1" PIPE; trap; \ echo 2; kill -s PIPE $$; trap; echo 3') 0 trap -- 'echo 1' PIPE 2 trap -- 'echo 1' PIPE 3 > > tests: work even if SIGPIPE is ignored > * tests/epipe: Do not infinite-loop if SIGPIPE is already ignored. > It could be that the invoker of 'make check' ignores SIGPIPE, > for example. > diff --git a/tests/epipe b/tests/epipe > index 336d994..f9cb3f6 100755 > --- a/tests/epipe > +++ b/tests/epipe > @@ -6,7 +6,7 @@ > > if > ( > - while :; do echo x; done | > + (trap - PIPE; while echo x; do :; done) 3>&- | So this won't work reliably, and can still inf-loop if epipe is executed from an environment with SIGPIPE ignored. The _only_ way to reset SIGPIPE out of not being ignored is to execute an intermediary program that doesn't share the shell's lame POSIX restriction. I almost wonder if coreutils should add a way to reset signals, perhaps as a new option to env, as in: env --reset-signal=PIPE echo x Obviously, if we add that extension to coreutils, you'd have to mark this particular grep test as skipped on platforms that lack env --reset-signal, and where we can detect either detect that SIGPIPE is ignored by the shell, or where we can detect that the shell is not know for its ability to tell us the truth about whether SIGPIPE is ignored. -- Eric Blake [email protected] +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature
