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:
parent
9f82b53c95
commit
135421ddbf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=38950
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user