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 Jul 16,  6:24pm, Vincent Lefevre wrote:
}
} Well, since bash implements WCE and is the default shell on Linux and
} Mac OS X machines, I'd say that such ill-behaved programs should not
} be common (and should be fixed). So, IMHO, there would be more benefit
} to have WCE in zsh.

So I investigated this a bit further and re-learned something I'd long
forgotten:

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.

In reminding myself of this, I believe I've also remembered the reason
that it ended up this way, which leads to points of disagreement with
the analysis in http://www.cons.org/cracauer/sigint.html (source of
the IUE/WUE/WCE abbreviations).

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.

My recollection now, which may be wrong, is that there was a considerable
debate about this several years ago, leading to the decision to simply
stick with the default signal handling when the shell is not interactive,
for any signal that it isn't otherwise absolutely necessary to handle.

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.

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.

(2) Both the exiting and the waiting normally take place in zhandler()
when the signal in question arrives.  This means that to get the option
right, we have to record the state of both signals and then find a
common place guaranteed to be outside the race where we can examine
the combined state.

There might be enough state currently available in zhandler() to test
it on either signal and do the correct thing, but I'm not sure yet.



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