1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-19 02:29:40 +00:00

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
This commit is contained in:
Martin Cracauer 1998-02-06 18:14:26 +00:00
parent 663690b388
commit 9dee16dba6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=33138

View File

@ -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