Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X

On 2009-07-17 22:29:36 -0700, Bart Schaefer wrote:
> When running a shell script (not interactively), zsh does NO HANDLING
> of SIGINT whatsoever.  It's implementing IUE, not WUE.  Or to be more
> precise, it's implementing the default behavior on SIGINT, which is
> usually to exit.

Yes, this is what I can see with zsh 4.3.10 (but zsh 4.2.3 implemented

> The point I believe Cracauer is overlooking is that the CALLER of the
> shell script may have specified that SIGINT is to be ignored.  SIG_IGN
> is supposed to be inherited by child processes; but to implement WUE
> or WCE, the shell must itself either ignore or handle SIGINT, which
> may contradict what the caller has requested.

I don't think that the caller should enforce what its children should
do. Many programs will set their own SIGINT handler, even if the caller
chose to ignore this signal. Anyway, even though bash implements WCE,
it ignores SIGINT if the caller chose to ignore it; also when executing
a process, it restores the trap to the default behavior, in case it was
ignored (that's another difference with zsh).

For instance, you can try with the following script with both bash
and zsh:

echo "Caller: $$"
cmd="echo \"Callee: \$\$ ($SHELL)\"; sleep 6; echo OK"
trp="trap 'echo SIGINT; exit' INT; $cmd"

echo "Send SIGINT to each callee's PID"

$SHELL -c "$cmd"; echo "Callee's exit status: $?"
$SHELL -c "$trp"; echo "Callee's exit status: $?"

trap ''  INT
echo "SIGINT ignored"

$SHELL -c "$cmd"; echo "Callee's exit status: $?"
$SHELL -c "$trp"; echo "Callee's exit status: $?"

trap 'echo "Caller received SIGINT"'  INT
echo "Type Ctrl-C in the terminal"

$SHELL -c "$cmd"; echo "Callee's exit status: $?"
$SHELL -c "$trp"; echo "Callee's exit status: $?"

Try also "killall -INT sleep" in the 6 cases.

> Further I think Cracauer is very wrong here:
>   Do nothing special when SIGINT appears while you wait for a child. You
>   don't even have to remember that one happened.
>   ...
>   Look at WIFSIGNALED(status) and WTERMSIG(status) to tell whether the
>   child says "I exited on SIGINT: in my opinion the user wants the
>   shellscript to be discontinued".
> This is plain nonsense.
> Not only does this potentially contradict a caller's explicit request
> to ignore SIGINT, but the script should not exit 130 every time any
> child exits 130.  It should exit only when SIGINT was received *by the
> script*.  "kill -INT ..." of the child should not cause the shell to
> behave as if it was interrupted.  Try it with bash.

It seems that bash behaves correctly in all those cases. If the caller
ignores SIGINT, then bash also ignores it. Moreover bash terminates
with exit status 130 only when it receives SIGINT and the child
terminates with exit status 130. (I've tried on a Linux machine with
bash 3.2 because I don't have access to my Mac OS X machine right

> Having said all that, I also looked at what it would take to implement
> WCE as an option.  There are two complications here:
> (1) There's a race condition as to whether the shell receives SIGINT
> or SIGCHLD first.  With enough trials I can get it to happen either
> way, though the vast majority of the time the SIGINT wins.

How does bash handle that?

BTW, I wonder why typing Ctrl-g in emacs sends SIGINT to the parent
under Mac OS X, but not under Linux.

Vincent Lefèvre <vincent@xxxxxxxxxx> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Messages sorted by: Reverse Date, Date, Thread, Author