ash: fix bug which causes signal6.tests to fail
function old new delta trapcmd 271 277 +6 localcmd 277 275 -2 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
51b4a9e2f1
commit
238bf187ba
@ -178,7 +178,7 @@ static NOINLINE void INET_setroute(int action, char **args)
|
|||||||
int prefix_len;
|
int prefix_len;
|
||||||
|
|
||||||
prefix_len = xatoul_range(prefix+1, 0, 32);
|
prefix_len = xatoul_range(prefix+1, 0, 32);
|
||||||
mask_in_addr(rt) = htonl( ~ (0xffffffffUL >> prefix_len));
|
mask_in_addr(rt) = htonl( ~(0xffffffffUL >> prefix_len));
|
||||||
*prefix = '\0';
|
*prefix = '\0';
|
||||||
#if HAVE_NEW_ADDRT
|
#if HAVE_NEW_ADDRT
|
||||||
rt.rt_genmask.sa_family = AF_INET;
|
rt.rt_genmask.sa_family = AF_INET;
|
||||||
|
22
shell/ash.c
22
shell/ash.c
@ -208,6 +208,7 @@ struct globals_misc {
|
|||||||
|
|
||||||
/* indicates specified signal received */
|
/* indicates specified signal received */
|
||||||
uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
|
uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
|
||||||
|
uint8_t may_have_traps; /* 0: definitely no traps are set, 1: some traps may be set */
|
||||||
char *trap[NSIG];
|
char *trap[NSIG];
|
||||||
char **trap_ptr; /* used only by "trap hack" */
|
char **trap_ptr; /* used only by "trap hack" */
|
||||||
|
|
||||||
@ -236,6 +237,7 @@ extern struct globals_misc *const ash_ptr_to_globals_misc;
|
|||||||
#define optlist (G_misc.optlist )
|
#define optlist (G_misc.optlist )
|
||||||
#define sigmode (G_misc.sigmode )
|
#define sigmode (G_misc.sigmode )
|
||||||
#define gotsig (G_misc.gotsig )
|
#define gotsig (G_misc.gotsig )
|
||||||
|
#define may_have_traps (G_misc.may_have_traps )
|
||||||
#define trap (G_misc.trap )
|
#define trap (G_misc.trap )
|
||||||
#define trap_ptr (G_misc.trap_ptr )
|
#define trap_ptr (G_misc.trap_ptr )
|
||||||
#define random_gen (G_misc.random_gen )
|
#define random_gen (G_misc.random_gen )
|
||||||
@ -333,7 +335,7 @@ raise_interrupt(void)
|
|||||||
/* Signal is not automatically unmasked after it is raised,
|
/* Signal is not automatically unmasked after it is raised,
|
||||||
* do it ourself - unmask all signals */
|
* do it ourself - unmask all signals */
|
||||||
sigprocmask_allsigs(SIG_UNBLOCK);
|
sigprocmask_allsigs(SIG_UNBLOCK);
|
||||||
/* pending_sig = 0; - now done in onsig() */
|
/* pending_sig = 0; - now done in signal_handler() */
|
||||||
|
|
||||||
ex_type = EXSIG;
|
ex_type = EXSIG;
|
||||||
if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
|
if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
|
||||||
@ -3268,10 +3270,10 @@ ignoresig(int signo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Signal handler. Only one usage site - in setsignal()
|
* Only one usage site - in setsignal()
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
onsig(int signo)
|
signal_handler(int signo)
|
||||||
{
|
{
|
||||||
gotsig[signo - 1] = 1;
|
gotsig[signo - 1] = 1;
|
||||||
|
|
||||||
@ -3366,7 +3368,7 @@ setsignal(int signo)
|
|||||||
act.sa_handler = SIG_DFL;
|
act.sa_handler = SIG_DFL;
|
||||||
switch (new_act) {
|
switch (new_act) {
|
||||||
case S_CATCH:
|
case S_CATCH:
|
||||||
act.sa_handler = onsig;
|
act.sa_handler = signal_handler;
|
||||||
act.sa_flags = 0; /* matters only if !DFL and !IGN */
|
act.sa_flags = 0; /* matters only if !DFL and !IGN */
|
||||||
sigfillset(&act.sa_mask); /* ditto */
|
sigfillset(&act.sa_mask); /* ditto */
|
||||||
break;
|
break;
|
||||||
@ -8443,15 +8445,16 @@ evalsubshell(union node *n, int flags)
|
|||||||
int status;
|
int status;
|
||||||
|
|
||||||
expredir(n->nredir.redirect);
|
expredir(n->nredir.redirect);
|
||||||
if (!backgnd && flags & EV_EXIT && !trap[0])
|
if (!backgnd && (flags & EV_EXIT) && !may_have_traps)
|
||||||
goto nofork;
|
goto nofork;
|
||||||
INT_OFF;
|
INT_OFF;
|
||||||
jp = makejob(/*n,*/ 1);
|
jp = makejob(/*n,*/ 1);
|
||||||
if (forkshell(jp, n, backgnd) == 0) {
|
if (forkshell(jp, n, backgnd) == 0) {
|
||||||
|
/* child */
|
||||||
INT_ON;
|
INT_ON;
|
||||||
flags |= EV_EXIT;
|
flags |= EV_EXIT;
|
||||||
if (backgnd)
|
if (backgnd)
|
||||||
flags &=~ EV_TESTED;
|
flags &= ~EV_TESTED;
|
||||||
nofork:
|
nofork:
|
||||||
redirect(n->nredir.redirect, 0);
|
redirect(n->nredir.redirect, 0);
|
||||||
evaltreenr(n->nredir.n, flags);
|
evaltreenr(n->nredir.n, flags);
|
||||||
@ -9193,16 +9196,19 @@ evalcommand(union node *cmd, int flags)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Fork off a child process if necessary. */
|
/* Fork off a child process if necessary. */
|
||||||
if (!(flags & EV_EXIT) || trap[0]) {
|
if (!(flags & EV_EXIT) || may_have_traps) {
|
||||||
INT_OFF;
|
INT_OFF;
|
||||||
jp = makejob(/*cmd,*/ 1);
|
jp = makejob(/*cmd,*/ 1);
|
||||||
if (forkshell(jp, cmd, FORK_FG) != 0) {
|
if (forkshell(jp, cmd, FORK_FG) != 0) {
|
||||||
|
/* parent */
|
||||||
exitstatus = waitforjob(jp);
|
exitstatus = waitforjob(jp);
|
||||||
INT_ON;
|
INT_ON;
|
||||||
TRACE(("forked child exited with %d\n", exitstatus));
|
TRACE(("forked child exited with %d\n", exitstatus));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* child */
|
||||||
FORCE_INT_ON;
|
FORCE_INT_ON;
|
||||||
|
/* fall through to exec'ing exeternal program */
|
||||||
}
|
}
|
||||||
listsetvar(varlist.list, VEXPORT|VSTACK);
|
listsetvar(varlist.list, VEXPORT|VSTACK);
|
||||||
shellexec(argv, path, cmdentry.u.index);
|
shellexec(argv, path, cmdentry.u.index);
|
||||||
@ -12349,6 +12355,8 @@ trapcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
|||||||
action = ckstrdup(action);
|
action = ckstrdup(action);
|
||||||
}
|
}
|
||||||
free(trap[signo]);
|
free(trap[signo]);
|
||||||
|
if (action)
|
||||||
|
may_have_traps = 1;
|
||||||
trap[signo] = action;
|
trap[signo] = action;
|
||||||
if (signo != 0)
|
if (signo != 0)
|
||||||
setsignal(signo);
|
setsignal(signo);
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
# Bug: TERM does not trigger in the child
|
|
||||||
{ trap "echo got TERM" TERM; sleep 3; }& sleep 1; kill $!; wait
|
{ trap "echo got TERM" TERM; sleep 3; }& sleep 1; kill $!; wait
|
||||||
echo Done: $?
|
echo Done: $?
|
||||||
|
Loading…
Reference in New Issue
Block a user