Be less conservative about when we do clear_traps() when we have
traps_invalid (that is, when we actually nuke the parent shell's caught traps in a subshell). This allows more reasonable use of "trap -p" (and similar) in subshells than existed before (and in particular, that command can be in a function now - there can also be several related commands like traps=$(trap -p INT; trap -p QUIT; trap -p HUP) A side effect of all of this is that (eval "$(trap -p)"; ...) now allows copying caught traps into a subshell environment, if desired. Also att the ksh93 variant (the one not picked by POSIX as it isn't generally as useful) of "trap -p" (but call it "trap -P" which extracts just the trap action for named signals (giving more than one is usually undesirable). This allows eval "$(trap -P INT)" to run the action for SIGINT traps, without needing to attempt to parse the "trap -p" output.
This commit is contained in:
parent
7a2f8a050c
commit
4a370dce6a
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: eval.c,v 1.180 2020/05/14 08:34:17 msaitoh Exp $ */
|
/* $NetBSD: eval.c,v 1.181 2020/08/20 23:09:56 kre Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1993
|
* Copyright (c) 1993
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95";
|
static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: eval.c,v 1.180 2020/05/14 08:34:17 msaitoh Exp $");
|
__RCSID("$NetBSD: eval.c,v 1.181 2020/08/20 23:09:56 kre Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
|
@ -280,8 +280,10 @@ evaltree(union node *n, int flags)
|
||||||
next = NULL;
|
next = NULL;
|
||||||
CTRACE(DBG_EVAL, ("pid %d, evaltree(%p: %s(%d), %#x) called\n",
|
CTRACE(DBG_EVAL, ("pid %d, evaltree(%p: %s(%d), %#x) called\n",
|
||||||
getpid(), n, NODETYPENAME(n->type), n->type, flags));
|
getpid(), n, NODETYPENAME(n->type), n->type, flags));
|
||||||
|
/*
|
||||||
if (n->type != NCMD && traps_invalid)
|
if (n->type != NCMD && traps_invalid)
|
||||||
free_traps();
|
free_traps();
|
||||||
|
*/
|
||||||
switch (n->type) {
|
switch (n->type) {
|
||||||
case NSEMI:
|
case NSEMI:
|
||||||
evaltree(n->nbinary.ch1, sflags);
|
evaltree(n->nbinary.ch1, sflags);
|
||||||
|
@ -302,6 +304,8 @@ evaltree(union node *n, int flags)
|
||||||
next = n->nbinary.ch2;
|
next = n->nbinary.ch2;
|
||||||
break;
|
break;
|
||||||
case NREDIR:
|
case NREDIR:
|
||||||
|
if (traps_invalid)
|
||||||
|
free_traps();
|
||||||
evalredir(n, flags);
|
evalredir(n, flags);
|
||||||
break;
|
break;
|
||||||
case NSUBSHELL:
|
case NSUBSHELL:
|
||||||
|
@ -309,9 +313,13 @@ evaltree(union node *n, int flags)
|
||||||
do_etest = !(flags & EV_TESTED);
|
do_etest = !(flags & EV_TESTED);
|
||||||
break;
|
break;
|
||||||
case NBACKGND:
|
case NBACKGND:
|
||||||
|
if (traps_invalid)
|
||||||
|
free_traps();
|
||||||
evalsubshell(n, flags);
|
evalsubshell(n, flags);
|
||||||
break;
|
break;
|
||||||
case NIF: {
|
case NIF: {
|
||||||
|
if (traps_invalid)
|
||||||
|
free_traps();
|
||||||
evaltree(n->nif.test, EV_TESTED);
|
evaltree(n->nif.test, EV_TESTED);
|
||||||
if (nflag || evalskip)
|
if (nflag || evalskip)
|
||||||
goto out1;
|
goto out1;
|
||||||
|
@ -325,15 +333,23 @@ evaltree(union node *n, int flags)
|
||||||
}
|
}
|
||||||
case NWHILE:
|
case NWHILE:
|
||||||
case NUNTIL:
|
case NUNTIL:
|
||||||
|
if (traps_invalid)
|
||||||
|
free_traps();
|
||||||
evalloop(n, sflags);
|
evalloop(n, sflags);
|
||||||
break;
|
break;
|
||||||
case NFOR:
|
case NFOR:
|
||||||
|
if (traps_invalid)
|
||||||
|
free_traps();
|
||||||
evalfor(n, sflags);
|
evalfor(n, sflags);
|
||||||
break;
|
break;
|
||||||
case NCASE:
|
case NCASE:
|
||||||
|
if (traps_invalid)
|
||||||
|
free_traps();
|
||||||
evalcase(n, sflags);
|
evalcase(n, sflags);
|
||||||
break;
|
break;
|
||||||
case NDEFUN:
|
case NDEFUN:
|
||||||
|
if (traps_invalid)
|
||||||
|
free_traps();
|
||||||
CTRACE(DBG_EVAL, ("Defining fn %s @%d%s\n",
|
CTRACE(DBG_EVAL, ("Defining fn %s @%d%s\n",
|
||||||
n->narg.text, n->narg.lineno,
|
n->narg.text, n->narg.lineno,
|
||||||
fnline1 ? " LINENO=1" : ""));
|
fnline1 ? " LINENO=1" : ""));
|
||||||
|
@ -350,6 +366,8 @@ evaltree(union node *n, int flags)
|
||||||
exitstatus = 1;
|
exitstatus = 1;
|
||||||
break;
|
break;
|
||||||
case NPIPE:
|
case NPIPE:
|
||||||
|
if (traps_invalid)
|
||||||
|
free_traps();
|
||||||
evalpipe(n);
|
evalpipe(n);
|
||||||
do_etest = !(flags & EV_TESTED);
|
do_etest = !(flags & EV_TESTED);
|
||||||
break;
|
break;
|
||||||
|
@ -1043,6 +1061,10 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd)
|
||||||
* command eval trap
|
* command eval trap
|
||||||
* eval command trap
|
* eval command trap
|
||||||
* without zapping the traps completely, in all other cases we do.
|
* without zapping the traps completely, in all other cases we do.
|
||||||
|
* Function calls also do not zap the traps (but commands they execute
|
||||||
|
* probably will) - this allows a function like
|
||||||
|
* trapstate() { trap -p; }
|
||||||
|
* called as save_traps=$(trapstate).
|
||||||
*
|
*
|
||||||
* The test here permits eval "anything" but when evalstring() comes
|
* The test here permits eval "anything" but when evalstring() comes
|
||||||
* back here again, the "anything" will be validated.
|
* back here again, the "anything" will be validated.
|
||||||
|
@ -1055,6 +1077,7 @@ evalcommand(union node *cmd, int flgs, struct backcmd *backcmd)
|
||||||
* trapcmd() takes care of doing free_traps() if it is needed there.
|
* trapcmd() takes care of doing free_traps() if it is needed there.
|
||||||
*/
|
*/
|
||||||
if (traps_invalid &&
|
if (traps_invalid &&
|
||||||
|
cmdentry.cmdtype != CMDFUNCTION &&
|
||||||
((cmdentry.cmdtype!=CMDSPLBLTIN && cmdentry.cmdtype!=CMDBUILTIN) ||
|
((cmdentry.cmdtype!=CMDSPLBLTIN && cmdentry.cmdtype!=CMDBUILTIN) ||
|
||||||
(cmdentry.u.bltin != trapcmd && cmdentry.u.bltin != evalcmd)))
|
(cmdentry.u.bltin != trapcmd && cmdentry.u.bltin != evalcmd)))
|
||||||
free_traps();
|
free_traps();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: trap.c,v 1.54 2020/08/20 16:15:50 kre Exp $ */
|
/* $NetBSD: trap.c,v 1.55 2020/08/20 23:09:56 kre Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1991, 1993
|
* Copyright (c) 1991, 1993
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95";
|
static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: trap.c,v 1.54 2020/08/20 16:15:50 kre Exp $");
|
__RCSID("$NetBSD: trap.c,v 1.55 2020/08/20 23:09:56 kre Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
|
@ -232,6 +232,8 @@ trapcmd(int argc, char **argv)
|
||||||
ap = argv + 1;
|
ap = argv + 1;
|
||||||
|
|
||||||
CTRACE(DBG_TRAP, ("trapcmd: "));
|
CTRACE(DBG_TRAP, ("trapcmd: "));
|
||||||
|
if (argc == 3 && strcmp(ap[1], "--") == 0)
|
||||||
|
argc--;
|
||||||
if (argc == 2 && strcmp(*ap, "-l") == 0) {
|
if (argc == 2 && strcmp(*ap, "-l") == 0) {
|
||||||
CTRACE(DBG_TRAP, ("-l\n"));
|
CTRACE(DBG_TRAP, ("-l\n"));
|
||||||
out1str("EXIT");
|
out1str("EXIT");
|
||||||
|
@ -253,9 +255,9 @@ trapcmd(int argc, char **argv)
|
||||||
traps_invalid = 0;
|
traps_invalid = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (argc >= 2 && strcmp(*ap, "-p") == 0) {
|
if (argc >= 2 && (strcmp(*ap, "-p") == 0 || strcmp(*ap, "-P") == 0)) {
|
||||||
CTRACE(DBG_TRAP, ("-p "));
|
CTRACE(DBG_TRAP, ("%s ", *ap));
|
||||||
printonly = 1;
|
printonly = 1 + (ap[0][1] == 'p');
|
||||||
ap++;
|
ap++;
|
||||||
argc--;
|
argc--;
|
||||||
}
|
}
|
||||||
|
@ -265,6 +267,9 @@ trapcmd(int argc, char **argv)
|
||||||
ap++;
|
ap++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (printonly == 1 && argc < 2)
|
||||||
|
goto usage;
|
||||||
|
|
||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
|
@ -339,8 +344,10 @@ trapcmd(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc < 2) { /* there must be at least 1 condition */
|
if (argc < 2) { /* there must be at least 1 condition */
|
||||||
|
usage:
|
||||||
out2str("Usage: trap [-l]\n"
|
out2str("Usage: trap [-l]\n"
|
||||||
" trap -p [condition ...]\n"
|
" trap -p [condition ...]\n"
|
||||||
|
" trap -P condition ...\n"
|
||||||
" trap action condition ...\n"
|
" trap action condition ...\n"
|
||||||
" trap N condition ...\n");
|
" trap N condition ...\n");
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -365,12 +372,17 @@ trapcmd(int argc, char **argv)
|
||||||
* (action will always be "-") here, if someone
|
* (action will always be "-") here, if someone
|
||||||
* really wants to get that particular output
|
* really wants to get that particular output
|
||||||
*/
|
*/
|
||||||
out1str("trap -- ");
|
if (printonly == 1) {
|
||||||
if (trap[signo] == NULL)
|
if (trap[signo] != NULL)
|
||||||
out1str("-");
|
out1fmt("%s\n", trap[signo]);
|
||||||
else
|
} else {
|
||||||
print_quoted(trap[signo]);
|
out1str("trap -- ");
|
||||||
out1fmt(" %s\n", trap_signame(signo));
|
if (trap[signo] == NULL)
|
||||||
|
out1str("-");
|
||||||
|
else
|
||||||
|
print_quoted(trap[signo]);
|
||||||
|
out1fmt(" %s\n", trap_signame(signo));
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue