summaryrefslogtreecommitdiffstats
path: root/bin/sh/jobs.c
diff options
context:
space:
mode:
authorcracauer <cracauer@FreeBSD.org>1998-02-06 18:14:26 +0000
committercracauer <cracauer@FreeBSD.org>1998-02-06 18:14:26 +0000
commit69ec138f358c3e71925110f6c3885d7e2d26bdb7 (patch)
treeea2a7072ce0481640823b2c72b1c2ee439a00cf2 /bin/sh/jobs.c
parentd5b09c81eced1f16f3f4629fb7fbafca071830c8 (diff)
downloadFreeBSD-src-69ec138f358c3e71925110f6c3885d7e2d26bdb7.zip
FreeBSD-src-69ec138f358c3e71925110f6c3885d7e2d26bdb7.tar.gz
Fix handling of SIGINT/SIGQUIT for foreground subprocesses. Most
urgent need is when you run sh around a program that intentionally uses SIGQUIT/SIGINT for asynchronous events, i.e. $EDITOR started from system(2), like many mailers do. This fixes PR bin/1206 and possibly bin/4241. The solution committed has been tested for a large number of possible cases (see recent discussion on cvs-committers). I completed a make world, made sure 'make world' is interruptable and used the changed /bin/sh as a login shell all day, including job control and using SIGQUIT-catching programs (to write this message :-). PR: bin/1206 Reviewed by: discussion on cvs-commiters
Diffstat (limited to 'bin/sh/jobs.c')
-rw-r--r--bin/sh/jobs.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c
index a17b5d0..a75fae0 100644
--- a/bin/sh/jobs.c
+++ b/bin/sh/jobs.c
@@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: jobs.c,v 1.16 1997/08/18 02:53:19 steve Exp $
+ * $Id: jobs.c,v 1.17 1997/12/10 22:18:53 eivind Exp $
*/
#ifndef lint
@@ -85,6 +85,9 @@ MKINIT pid_t backgndpid = -1; /* pid of last background process */
int initialpgrp; /* pgrp of shell on invocation */
int curjob; /* current job */
#endif
+sig_t oldsigint;
+sig_t oldsigquit;
+int oldsigs_valid = 0;
#if JOBS
STATIC void restartjob __P((struct job *));
@@ -574,6 +577,11 @@ forkshell(jp, n, mode)
TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n,
mode));
INTOFF;
+ if (mode == FORK_FG) {
+ oldsigquit = signal(SIGQUIT,SIG_IGN);
+ oldsigint = signal(SIGINT,SIG_IGN);
+ oldsigs_valid = 1;
+ }
pid = fork();
if (pid == -1) {
TRACE(("Fork failed, errno=%d\n", errno));
@@ -586,6 +594,8 @@ forkshell(jp, n, mode)
int i;
TRACE(("Child shell %d\n", getpid()));
+ signal(SIGQUIT,SIG_DFL);
+ signal(SIGINT,SIG_DFL);
wasroot = rootshell;
rootshell = 0;
for (i = njobs, p = jobtab ; --i >= 0 ; p++)
@@ -700,6 +710,12 @@ waitforjob(jp)
while (jp->state == 0) {
dowait(1, jp);
}
+ if (oldsigs_valid) {
+ signal(SIGQUIT,oldsigquit);
+ signal(SIGINT,oldsigint);
+ oldsigs_valid = 0;
+ }
+
#if JOBS
if (jp->jobctl) {
#ifdef OLD_TTY_DRIVER
OpenPOWER on IntegriCloud