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/error.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/error.c')
-rw-r--r-- | bin/sh/error.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/bin/sh/error.c b/bin/sh/error.c index 9e383e3..0464f6e 100644 --- a/bin/sh/error.c +++ b/bin/sh/error.c @@ -39,7 +39,7 @@ static char sccsid[] = "@(#)error.c 8.2 (Berkeley) 5/4/95"; #endif static const char rcsid[] = - "$Id$"; + "$Id: error.c,v 1.10 1998/05/18 06:43:32 charnier Exp $"; #endif /* not lint */ /* @@ -52,6 +52,7 @@ static const char rcsid[] = #include "output.h" #include "error.h" #include "show.h" +#include "trap.h" #include <signal.h> #include <unistd.h> #include <errno.h> @@ -62,9 +63,9 @@ static const char rcsid[] = */ struct jmploc *handler; -int exception; -volatile int suppressint; -volatile int intpending; +volatile sig_atomic_t exception; +int suppressint; +volatile sig_atomic_t intpending; char *commandname; @@ -90,29 +91,43 @@ exraise(e) /* * Called from trap.c when a SIGINT is received. (If the user specifies * that SIGINT is to be trapped or ignored using the trap builtin, then - * this routine is not called.) Suppressint is nonzero when interrupts - * are held using the INTOFF macro. The call to _exit is necessary because - * there is a short period after a fork before the signal handlers are - * set to the appropriate value for the child. (The test for iflag is - * just defensive programming.) + * this routine is not called.) Supressint is nonzero when interrupts + * are held using the INTOFF macro. If SIGINTs are not suppressed and + * the shell is not a root shell, then we want to be terminated if we + * get here, as if we were terminated directly by a SIGINT. Arrange for + * this here. */ void onint() { sigset_t sigset; - if (suppressint) { + /* The !in_dotrap is save. The only way we can arrive here with + * in_dotrap set is that a trap handler set SIGINT to default + * and killed itself. + */ + + if (suppressint && !in_dotrap) { intpending++; return; } intpending = 0; sigemptyset(&sigset); sigprocmask(SIG_SETMASK, &sigset, NULL); - out2str("\n"); + + /* This doesn't seem to be needed. Note that main emit a newline + * as well. + */ +#if 0 + if (tcgetpgrp(0) == getpid()) + write(STDERR_FILENO, "\n", 1); +#endif if (rootshell && iflag) exraise(EXINT); - else - _exit(128 + SIGINT); + else { + signal(SIGINT, SIG_DFL); + kill(getpid(), SIGINT); + } } |