1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-24 11:29:10 +00:00

If traps are set, they are now executed even when a signal-blocking

foreground child is running. Formerly, traps were exceuted after the
next child exit.

The enables the user to put a breaking wrapper around a blocking
application:
  (trap 'echo trap ; exit 1' 2; ./pestyblocker; echo -n)

The "echo -n" after the child call is needed to prevent sh from
optimizing the trap-executing shell away. I'm working on this.
This commit is contained in:
Martin Cracauer 1998-09-08 13:16:52 +00:00
parent 9f82b53c95
commit 135421ddbf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=38950
3 changed files with 27 additions and 10 deletions

View File

@ -39,7 +39,7 @@
static char sccsid[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95";
#endif
static const char rcsid[] =
"$Id: jobs.c,v 1.21 1998/08/24 10:20:36 cracauer Exp $";
"$Id: jobs.c,v 1.22 1998/08/25 09:33:34 cracauer Exp $";
#endif /* not lint */
#include <fcntl.h>
@ -88,6 +88,7 @@ int initialpgrp; /* pgrp of shell on invocation */
int curjob; /* current job */
#endif
int in_waitcmd = 0; /* are we in waitcmd()? */
int in_dowait = 0; /* are we in dowait()? */
volatile sig_atomic_t breakwaitcmd = 0; /* should wait be terminated? */
#if JOBS
@ -712,9 +713,9 @@ waitforjob(jp)
INTOFF;
TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1));
while (jp->state == 0) {
dowait(1, jp);
}
while (jp->state == 0)
if (dowait(1, jp) == -1)
dotrap();
#if JOBS
if (jp->jobctl) {
#ifdef OLD_TTY_DRIVER
@ -771,11 +772,13 @@ dowait(block, job)
int core;
int sig;
in_dowait++;
TRACE(("dowait(%d) called\n", block));
do {
pid = waitproc(block, &status);
TRACE(("wait returns %d, status=%d\n", pid, status));
} while (pid == -1 && errno == EINTR && breakwaitcmd == 0);
in_dowait--;
if (breakwaitcmd != 0) {
breakwaitcmd = 0;
return -1;

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)jobs.h 8.2 (Berkeley) 5/4/95
* $Id: jobs.h,v 1.7 1998/08/24 10:20:36 cracauer Exp $
* $Id: jobs.h,v 1.8 1998/08/25 09:33:34 cracauer Exp $
*/
/* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
@ -79,6 +79,7 @@ struct job {
extern pid_t backgndpid; /* pid of last background process */
extern int job_warning; /* user was warned about stopped jobs */
extern int in_waitcmd; /* are we in waitcmd()? */
extern int in_dowait; /* are we in dowait()? */
extern volatile sig_atomic_t breakwaitcmd; /* should wait be terminated? */
void setjobctl __P((int));

View File

@ -39,7 +39,7 @@
static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95";
#endif
static const char rcsid[] =
"$Id: trap.c,v 1.13 1998/08/25 08:49:47 cracauer Exp $";
"$Id: trap.c,v 1.14 1998/08/25 09:33:34 cracauer Exp $";
#endif /* not lint */
#include <signal.h>
@ -77,7 +77,7 @@ static const char rcsid[] =
MKINIT char sigmode[NSIG]; /* current value of signal */
int pendingsigs; /* indicates some signal received */
int in_dotrap; /* do we execute in a trap handler? */
static char *trap[NSIG]; /* trap handler commands */
static char *volatile trap[NSIG]; /* trap handler commands */
static volatile sig_atomic_t gotsig[NSIG];
/* indicates specified signal received */
static int ignore_sigchld; /* Used while handling SIGCHLD traps. */
@ -190,7 +190,7 @@ trapcmd(argc, argv)
void
clear_traps()
{
char **tp;
char *volatile *tp;
for (tp = trap ; tp <= &trap[NSIG - 1] ; tp++) {
if (*tp && **tp) { /* trap not NULL or SIG_IGN */
@ -347,6 +347,7 @@ void
onsig(signo)
int signo;
{
int i;
#ifndef BSD
signal(signo, onsig);
@ -355,12 +356,24 @@ onsig(signo)
onint();
return;
}
if (signo != SIGCHLD || !ignore_sigchld)
gotsig[signo] = 1;
pendingsigs++;
if (signo == SIGINT && in_waitcmd != 0) {
dotrap();
/* If we are currently in a wait builtin, prepare to break it */
if ((signo == SIGINT || signo == SIGQUIT) && in_waitcmd != 0)
breakwaitcmd = 1;
/*
* If a trap is set, we need to make sure it is executed even
* when a childs blocks all signals.
*/
for (i = 0; i < NSIG; i++) {
if (signo == i && trap[i] != NULL &&
! (trap[i][0] == ':' && trap[i][1] == '\0')) {
breakwaitcmd = 1;
break;
}
}
}