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

Traps called for child signals

This is what I mentioned in the fix for traps with interrupted shell
structures yesterday evening.

There's code in zsh to call a trap for e.g. SIGINT if it was actually
a child that got the signal (ksh does this too).  Unfortunately it
doesn't work at the moment because errflag is being set in printjob()
which means the trap code barfs.  I don't know when this got broken
and if anybody can shed some light on the rational for it I'd like to

The answer is simply to set errflag = 0 before calling the trap.
That's because (as documented in the entry for `return' in the
zshbuiltins manual page) returning from a trap either continues the
job (zero return status) or aborts it (non zero return status), so the
previous errflag is not useful.  (Ksh doesn't have this feature, but
it does seem extremely useful; what ksh has instead is traps local to
functions which are called in the environment of that function,
i.e. traps are eval'd instead of themselves called as functions --- so
you can actually return from a function within the trap.)

HM Government Health Warning:  setting errflag to zero in general can
seriously damage your shell.

The point about the `breaks = loops' test is the way errors are
handled by the if/for/while/... code:  if errflag is found, lastval is
set to 1, so you lose the usual 128+SIGNO value.  If the loop is to
exited, however, the previous value is retained.  This seems
preferable in this case.

*** Src/jobs.c.trp	Wed May 31 05:10:22 1995
--- Src/jobs.c	Fri Jun  9 14:13:28 1995
*** 157,163 ****
--- 157,178 ----
      /* If the foreground job got a signal, pretend we got it, too.   */
      if (inforeground && WIFSIGNALED(status)) {
  	if (sigtrapped[WTERMSIG(status)]) {
+ 	    /* Run the trap with the error flag unset.
+ 	     * Errflag is set in printjobs if the jobs terminated
+ 	     * with SIGINT.  I don't know why it's done there and
+ 	     * not here.   (PWS 1995/06/08)
+ 	     */
+ 	    errflag = 0;
+ 	    /* We keep the errflag as set or not by dotrap.
+ 	     * This is to fulfil the promise to carry on
+ 	     * with the jobs if trap returns zero.
+ 	     * Setting breaks = loops ensures a consistent return
+ 	     * status if inside a loop.  Maybe the code in loops
+ 	     * should be changed.
+ 	     */
+ 	    if (errflag)
+ 		breaks = loops;
  	} else if (WTERMSIG(status) == SIGINT ||
  		   WTERMSIG(status) == SIGQUIT) {
  	    breaks = loops;

Peter Stephenson <P.Stephenson@xxxxxxxxxxxxx>  Tel: +44 1792 205678 extn. 4461
WWW:  http://python.swan.ac.uk/~pypeters/      Fax: +44 1792 295324
Department of Physics, University of Wales, Swansea,
Singleton Park, Swansea, SA2 8PP, U.K.

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