Skip to contentSkip to conversation

bug in handling of ignored traps

DISCUSSION Eric Blake 2 participants 2 messages Feb 8, 2012

lore
Share & tools
lore

Eric Blake

author
#0 lore raw

Per POSIX requirements on trap, dash is properly refusing to let non-interactive scripts reset signal handlers via trap if the shell was started with an inherited ignored signal handler. However, dash lies to the user, making it impossible to tell if the user is invoking a shell in an environment where a signal was inherited as ignored. ksh and bash are nicer about things, and at least let the user query whether a shell is treating a particular signal as non-resettable.

This is important for shell scripts that WANT to guarantee a particular behavior of SIGPIPE handling (such as this thread on writing a grep test for covering the behavior of grep both with and without SIGPIPE inherited as ignored:
https://lists.gnu.org/archive/html/bug-grep/2012-02/msg00016.html).

Bash behavior - you can learn about the ignored handler from the get-go:

$ (trap '' PIPE; bash -c 'trap; echo 0; trap "echo 1" PIPE; trap; \
     echo 2; kill -s PIPE $$; trap; echo 3')
trap -- '' SIGPIPE
0
trap -- '' SIGPIPE
2
trap -- '' SIGPIPE
3

Ksh behavior - you can learn about the ignored handler, but only after trying to use something else:

$ (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

dash behavior - the trap is properly ignored, but you can't learn about it (that is, trap lies and tells you that the handler was changed):

$ (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

and proof that when the inheritance issue is not in play, the handler works:

$ (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
1
trap -- 'echo 1' PIPE
3
Signature · 2 lines
Eric Blake   [email protected]    +1-919-301-3266
Libvirt virtualization library http://libvirt.org
#1 lore raw
Quoted 7 lines

Per POSIX requirements on trap, dash is properly refusing to let non-interactive scripts reset signal handlers via trap if the shell was started with an inherited ignored signal handler. However, dash lies to the user, making it impossible to tell if the user is invoking a shell in an environment where a signal was inherited as ignored. ksh and bash are nicer about things, and at least let the user query whether a shell is treating a particular signal as non-resettable.

I don't think this is a bug. It's more of a quality-of-implementation issue. dash appears to be following the "no error need be reported when attempting to do so" part of the Posix spec, which is fine. Bash did more or less the same thing until bash-4.2.

Chet

Signature · 3 lines
``The lyf so short, the craft so long to lerne.'' - Chaucer
		 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU    [email protected]    http://cnswww.cns.cwru.edu/~chet/