On Monday 12 September 2011, Stefano Lattarini wrote: > Now some updates: the "default" Korn Shell on Debian GNU/Linux (package > `ksh', version `93u-1') seems to exhibit the same issue: > > $ ksh -c "perl -e 'kill 2, \$\$'; :"; echo $? > 130 > > And if I'm not reading the strace output wrong, this is due to the fact > that the Debian korn shell is apparently killing itself (yikes!) with the > same signal that killed the child process: > > $ strace ksh -c "perl -e 'kill 2, \$\$'; :" > ... > getpid() = 15108 > ... > lstat64("/usr/bin/perl", {st_mode=S_IFREG|0755, st_size=1437872, ...}) = 0 > rt_sigprocmask(SIG_BLOCK, [HUP INT QUIT PIPE], [], 8) = 0 > vfork() = 15109 > --- SIGCHLD (Child exited) @ 0 (0) --- > sigreturn() = ? (mask now [HUP INT QUIT PIPE]) > rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 > waitpid(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGINT}], > WNOHANG|WSTOPPED|WCONTINUED) = 15109 > waitpid(-1, 0xbfa0270c, WNOHANG|WSTOPPED|WCONTINUED) = -1 ECHILD (No child > processes) > rt_sigaction(SIGCHLD, {0x806e390, [], SA_INTERRUPT}, {0x806e390, [], > SA_INTERRUPT}, 8) = 0 > rt_sigaction(SIGINT, {0x80603b0, [], SA_INTERRUPT}, {SIG_DFL, [], 0}, 8) = 0 > ioctl(2, TIOCGPGRP, [15107]) = 0 > rt_sigaction(SIGINT, {0x80603b0, [], SA_INTERRUPT}, {0x80603b0, [], > SA_INTERRUPT}, 8) = 0 > getrlimit(RLIMIT_CORE, {rlim_cur=0, rlim_max=RLIM_INFINITY}) = 0 > setrlimit(RLIMIT_CORE, {rlim_cur=0, rlim_max=RLIM_INFINITY}) = 0 > rt_sigaction(SIGINT, {SIG_DFL, [], SA_INTERRUPT}, {0x80603b0, [], > SA_INTERRUPT}, 8) = 0 > rt_sigprocmask(SIG_UNBLOCK, [INT], NULL, 8) = 0 > rt_sigprocmask(SIG_UNBLOCK, [INT], NULL, 8) = 0 > kill(15108, SIGINT) = 0 > --- SIGINT (Interrupt) @ 0 (0) --- > +++ killed by SIGINT +++ > > The truss output on Solaris is less clear (for me at least, I'm not used > to it), and I'm not at all sure that the issue there is due to the same > dynamics; more digging needed. > No, it's better on Solaris: its /bin/ksh (and /usr/xpg4/bin/sh) "only" exit with status 130 [*] if a child is terminated by a SIGINT; so the signal is not "recursively propagated".
[*] Well, it still executes the trap associated with SIGINT, but probably does so through special-cased code, without passing through real `kill' system calls. I guess. Examples: $ cat bar1.sh trap 'echo SIGINT; exit 99;' 2 /bin/ksh -c "perl -e 'kill 2, \$\$'; :"; echo $? echo alive $ /bin/ksh bar1.sh 130 alive $ cat bar2.sh /bin/ksh -c "/bin/ksh -c 'kill -2 \$\$'; echo \$?"; echo $? echo alive $ /bin/ksh bar2.sh 130 0 alive $ cat bar3.sh trap 'echo SIGINT; exit 99' 2 /bin/ksh -c " trap 'echo SIGINT; exit 99;' 2 perl -e 'kill 2, \$\$' :" echo $? echo alive $ /bin/ksh bar3.sh SIGINT 99 alive OTOH, the first and second scripts would behave much worse on Debian: $ /bin/ksh bar1.sh; echo $? SIGINT 99 $ /bin/ksh bar2.sh; echo $? 130 And with this, I think the issue has been explained. Now all it remains to do is document it in the automanual ;-) Regards, Stefano