mirror of
https://github.com/sheumann/hush.git
synced 2025-01-03 00:31:16 +00:00
ash: hopefully close bug 4324. With testcase.
function old new delta evaltree 621 869 +248 popstring 134 140 +6
This commit is contained in:
parent
2b2e267b43
commit
4e19a9c81a
53
shell/ash.c
53
shell/ash.c
@ -203,7 +203,7 @@ struct globals_misc {
|
|||||||
#define S_RESET 5 /* temporary - to reset a hard ignored sig */
|
#define S_RESET 5 /* temporary - to reset a hard ignored sig */
|
||||||
|
|
||||||
/* indicates specified signal received */
|
/* indicates specified signal received */
|
||||||
char gotsig[NSIG - 1];
|
char gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
|
||||||
char *trap[NSIG];
|
char *trap[NSIG];
|
||||||
|
|
||||||
/* Rarely referenced stuff */
|
/* Rarely referenced stuff */
|
||||||
@ -7846,12 +7846,12 @@ dotrap(void)
|
|||||||
pendingsig = 0;
|
pendingsig = 0;
|
||||||
xbarrier();
|
xbarrier();
|
||||||
|
|
||||||
for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) {
|
for (i = 1, q = gotsig; i < NSIG; i++, q++) {
|
||||||
if (!*q)
|
if (!*q)
|
||||||
continue;
|
continue;
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
|
|
||||||
p = trap[i + 1];
|
p = trap[i];
|
||||||
if (!p)
|
if (!p)
|
||||||
continue;
|
continue;
|
||||||
skip = evalstring(p, SKIPEVAL);
|
skip = evalstring(p, SKIPEVAL);
|
||||||
@ -7881,16 +7881,33 @@ static void prehash(union node *);
|
|||||||
static void
|
static void
|
||||||
evaltree(union node *n, int flags)
|
evaltree(union node *n, int flags)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct jmploc *volatile savehandler = exception_handler;
|
||||||
|
struct jmploc jmploc;
|
||||||
int checkexit = 0;
|
int checkexit = 0;
|
||||||
void (*evalfn)(union node *, int);
|
void (*evalfn)(union node *, int);
|
||||||
unsigned isor;
|
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (n == NULL) {
|
if (n == NULL) {
|
||||||
TRACE(("evaltree(NULL) called\n"));
|
TRACE(("evaltree(NULL) called\n"));
|
||||||
goto out;
|
goto out1;
|
||||||
}
|
}
|
||||||
TRACE(("pid %d, evaltree(%p: %d, %d) called\n",
|
TRACE(("pid %d, evaltree(%p: %d, %d) called\n",
|
||||||
getpid(), n, n->type, flags));
|
getpid(), n, n->type, flags));
|
||||||
|
|
||||||
|
exception_handler = &jmploc;
|
||||||
|
{
|
||||||
|
int err = setjmp(jmploc.loc);
|
||||||
|
if (err) {
|
||||||
|
/* if it was a signal, check for trap handlers */
|
||||||
|
if (exception == EXSIG)
|
||||||
|
goto out;
|
||||||
|
/* continue on the way out */
|
||||||
|
exception_handler = savehandler;
|
||||||
|
longjmp(exception_handler->loc, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
default:
|
default:
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@ -7936,19 +7953,20 @@ evaltree(union node *n, int flags)
|
|||||||
goto calleval;
|
goto calleval;
|
||||||
case NAND:
|
case NAND:
|
||||||
case NOR:
|
case NOR:
|
||||||
case NSEMI:
|
case NSEMI: {
|
||||||
|
|
||||||
#if NAND + 1 != NOR
|
#if NAND + 1 != NOR
|
||||||
#error NAND + 1 != NOR
|
#error NAND + 1 != NOR
|
||||||
#endif
|
#endif
|
||||||
#if NOR + 1 != NSEMI
|
#if NOR + 1 != NSEMI
|
||||||
#error NOR + 1 != NSEMI
|
#error NOR + 1 != NSEMI
|
||||||
#endif
|
#endif
|
||||||
isor = n->type - NAND;
|
unsigned is_or = is_or = n->type - NAND;
|
||||||
evaltree(
|
evaltree(
|
||||||
n->nbinary.ch1,
|
n->nbinary.ch1,
|
||||||
(flags | ((isor >> 1) - 1)) & EV_TESTED
|
(flags | ((is_or >> 1) - 1)) & EV_TESTED
|
||||||
);
|
);
|
||||||
if (!exitstatus == isor)
|
if (!exitstatus == is_or)
|
||||||
break;
|
break;
|
||||||
if (!evalskip) {
|
if (!evalskip) {
|
||||||
n = n->nbinary.ch2;
|
n = n->nbinary.ch2;
|
||||||
@ -7959,6 +7977,7 @@ evaltree(union node *n, int flags)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case NIF:
|
case NIF:
|
||||||
evaltree(n->nif.test, EV_TESTED);
|
evaltree(n->nif.test, EV_TESTED);
|
||||||
if (evalskip)
|
if (evalskip)
|
||||||
@ -7979,8 +7998,11 @@ evaltree(union node *n, int flags)
|
|||||||
exitstatus = status;
|
exitstatus = status;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if ((checkexit & exitstatus))
|
exception_handler = savehandler;
|
||||||
|
out1:
|
||||||
|
if (checkexit & exitstatus)
|
||||||
evalskip |= SKIPEVAL;
|
evalskip |= SKIPEVAL;
|
||||||
else if (pendingsig && dotrap())
|
else if (pendingsig && dotrap())
|
||||||
goto exexit;
|
goto exexit;
|
||||||
@ -11907,18 +11929,15 @@ trapcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
|||||||
if (!*ap) {
|
if (!*ap) {
|
||||||
for (signo = 0; signo < NSIG; signo++) {
|
for (signo = 0; signo < NSIG; signo++) {
|
||||||
if (trap[signo] != NULL) {
|
if (trap[signo] != NULL) {
|
||||||
const char *sn;
|
|
||||||
|
|
||||||
sn = get_signame(signo);
|
|
||||||
out1fmt("trap -- %s %s\n",
|
out1fmt("trap -- %s %s\n",
|
||||||
single_quote(trap[signo]), sn);
|
single_quote(trap[signo]),
|
||||||
|
get_signame(signo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!ap[1])
|
action = NULL;
|
||||||
action = NULL;
|
if (ap[1])
|
||||||
else
|
|
||||||
action = *ap++;
|
action = *ap++;
|
||||||
while (*ap) {
|
while (*ap) {
|
||||||
signo = get_signum(*ap);
|
signo = get_signum(*ap);
|
||||||
|
3
shell/ash_test/ash-signals/signal2.right
Normal file
3
shell/ash_test/ash-signals/signal2.right
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
sleeping
|
||||||
|
child exits as expected
|
||||||
|
parent exits
|
18
shell/ash_test/ash-signals/signal2.tests
Executable file
18
shell/ash_test/ash-signals/signal2.tests
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
$THIS_SH -c '
|
||||||
|
cleanup() {
|
||||||
|
echo "child exits as expected"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
trap cleanup HUP
|
||||||
|
echo "sleeping"
|
||||||
|
sleep 1
|
||||||
|
echo "BAD exit from child!"
|
||||||
|
' &
|
||||||
|
|
||||||
|
child=$!
|
||||||
|
sleep 0.1 # let child install handler first
|
||||||
|
kill -HUP $child
|
||||||
|
wait
|
||||||
|
echo "parent exits"
|
Loading…
Reference in New Issue
Block a user