From d067ebcacd55472f720b2765ec686a69b25c9a90 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 7 Dec 2014 16:24:19 +0000 Subject: 33876: etc.: Separate errors and keyboards interrupts Combination of 12 commits from interrupt_abort branch. Basic strategy is to introduce bits to errflag and to set and reset them separately. Remove interrupt status on return to main keymap. Turn off ERRFLAG_INT for always block. Restore bit thereafter: we probably need a new variable in order to allow user interrupts to be reset in the always block. Add TRY_BLOCK_INTERRUPT This works the same as TRY_BLOCK_ERROR, but for a SIGINT, too. Ensure propagation of SIGINT from exited job. If received by foreground job, shell uses ERRFLAG_INT, not ERRFLAG_ERROR, to set the new state. Reset errflag before precmd() Add always block in _main_completion to fix ZLS_COLORS Ensures we get the right state of $ZLS_COLORS at the end of _main_complete even if there's an interrupt. However, the "right state" is a bit messy as it depends on styles. --- Src/signals.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'Src/signals.c') diff --git a/Src/signals.c b/Src/signals.c index e72850516..899f1217b 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -619,7 +619,7 @@ zhandler(int sig) zexit(SIGINT, 1); if (list_pipe || chline || simple_pline) { breaks = loops; - errflag = 1; + errflag |= ERRFLAG_INT; inerrflush(); check_cursh_sig(SIGINT); } @@ -640,6 +640,11 @@ zhandler(int sig) if (idle >= 0 && idle < tmout) alarm(tmout - idle); else { + /* + * We want to exit now. + * Cancel all errors, including a user interrupt + * which is now redundant. + */ errflag = noerrs = 0; zwarn("timeout"); stopmsg = 1; @@ -1267,7 +1272,18 @@ dotrapargs(int sig, int *sigtr, void *sigfn) !(isfunc && new_trap_return == 0)) { if (isfunc) { breaks = loops; - errflag = 1; + /* + * For SIGINT we behave the same as the default behaviour + * i.e. we set the error bit indicating an interrupt. + * We do this with SIGQUIT, too, even though we don't + * handle SIGQUIT by default. That's to try to make + * it behave a bit more like its normal behaviour when + * the trap handler has told us that's what it wants. + */ + if (sig == SIGINT || sig == SIGQUIT) + errflag |= ERRFLAG_INT; + else + errflag |= ERRFLAG_ERROR; } lastval = new_trap_return; /* return triggered */ @@ -1282,8 +1298,12 @@ dotrapargs(int sig, int *sigtr, void *sigfn) */ lastval = olastval; } - if (try_tryflag) - errflag = traperr; + if (try_tryflag) { + if (traperr) + errflag |= ERRFLAG_ERROR; + else + errflag &= ~ERRFLAG_ERROR; + } breaks += obreaks; /* return not triggered: restore old flag */ retflag = oretflag; -- cgit 1.4.1