diff options
author | cracauer <cracauer@FreeBSD.org> | 1998-08-24 10:20:37 +0000 |
---|---|---|
committer | cracauer <cracauer@FreeBSD.org> | 1998-08-24 10:20:37 +0000 |
commit | 8a3c521f04ee9ad807d4c737f050230cb04ce36d (patch) | |
tree | 8ccf28d7f10330488ab5bce78116d30f74886c79 /bin/sh/trap.c | |
parent | f3d290b0b53aa55bf027aba6c54dd0e5b1d101f3 (diff) | |
download | FreeBSD-src-8a3c521f04ee9ad807d4c737f050230cb04ce36d.zip FreeBSD-src-8a3c521f04ee9ad807d4c737f050230cb04ce36d.tar.gz |
Do not exit on SIGINT in non-interactive shells, fixes PR 1206,
i.e. this makes emacs usable from system(3). Programs called from
shellscripts are now required to exit with proper signal status. That
means, they have to kill themself. Exiting with faked numerical exit
code is not sufficient.
Exit with proper signal status if script exits on signal.
Make the wait builtin interruptable, both with and without traps set.
Use volatile sig_atomic_t where (and only where) appropriate.
(Almost) fix printing of newlines on SIGINT.
Make traps setable from trap handlers. This is needed for shellscripts
that catch SIGINT for cleanup work but intend to exit on it, hance
have to kill themself from a trap handler. I.e. mkdep.
While I'm at it, make it -Wall clean. -Wall is not enabled in
Makefile, since vararg warnx() macro calls in usr.bin/printf/printf.c
are not -Wall-able.
PR: 1206
Obtained from: Basic SIGINT fix from Bruce Evans
Diffstat (limited to 'bin/sh/trap.c')
-rw-r--r-- | bin/sh/trap.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/bin/sh/trap.c b/bin/sh/trap.c index b21928f..c3ab48a 100644 --- a/bin/sh/trap.c +++ b/bin/sh/trap.c @@ -39,7 +39,7 @@ static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95"; #endif static const char rcsid[] = - "$Id$"; + "$Id: trap.c,v 1.11 1998/05/18 06:44:22 charnier Exp $"; #endif /* not lint */ #include <signal.h> @@ -75,9 +75,11 @@ static const char rcsid[] = MKINIT char sigmode[NSIG]; /* current value of signal */ -int pendingsigs; /* indicates some signal received */ +int pendingsigs; /* indicates some signal received */ +int in_dotrap = 0; /* Do we execute in a trap handler? */ static char *trap[NSIG]; /* trap handler commands */ -static char gotsig[NSIG]; /* indicates specified signal received */ +static volatile sig_atomic_t gotsig[NSIG]; + /* indicates specified signal received */ static int ignore_sigchld; /* Used while handling SIGCHLD traps. */ static int getsigaction __P((int, sig_t *)); @@ -221,11 +223,10 @@ setsignal(signo) action = S_CATCH; else action = S_IGN; - if (rootshell && action == S_DFL) { + if (action == S_DFL) { switch (signo) { case SIGINT: - if (iflag) - action = S_CATCH; + action = S_CATCH; break; case SIGQUIT: #ifdef DEBUG @@ -236,15 +237,16 @@ setsignal(signo) break; } #endif - /* FALLTHROUGH */ + action = S_IGN; + break; case SIGTERM: - if (iflag) + if (rootshell && iflag) action = S_IGN; break; #if JOBS case SIGTSTP: case SIGTTOU: - if (mflag) + if (rootshell && mflag) action = S_IGN; break; #endif @@ -356,6 +358,10 @@ onsig(signo) if (signo != SIGCHLD || !ignore_sigchld) gotsig[signo] = 1; pendingsigs++; + if (signo == SIGINT && in_waitcmd != 0) { + dotrap(); + breakwaitcmd = 1; + } } @@ -369,6 +375,7 @@ dotrap() int i; int savestatus; + in_dotrap++; for (;;) { for (i = 1; i < NSIG; i++) { if (gotsig[i]) { @@ -392,6 +399,7 @@ dotrap() if (i >= NSIG) break; } + in_dotrap--; pendingsigs = 0; } @@ -403,7 +411,7 @@ void setinteractive(on) int on; { - static int is_interactive = 0; + static int is_interactive = -1; if (on == is_interactive) return; |