Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/sh Be less conservative about when we do clear_traps() w...



details:   https://anonhg.NetBSD.org/src/rev/63e9cc5ce233
branches:  trunk
changeset: 937536:63e9cc5ce233
user:      kre <kre%NetBSD.org@localhost>
date:      Thu Aug 20 23:09:56 2020 +0000

description:
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.

diffstat:

 bin/sh/eval.c |  27 +++++++++++++++++++++++++--
 bin/sh/trap.c |  34 +++++++++++++++++++++++-----------
 2 files changed, 48 insertions(+), 13 deletions(-)

diffs (189 lines):

diff -r 9dc686dd8f1d -r 63e9cc5ce233 bin/sh/eval.c
--- a/bin/sh/eval.c     Thu Aug 20 23:03:17 2020 +0000
+++ b/bin/sh/eval.c     Thu Aug 20 23:09:56 2020 +0000
@@ -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
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)eval.c     8.9 (Berkeley) 6/8/95";
 #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 /* not lint */
 
@@ -280,8 +280,10 @@
                next = NULL;
                CTRACE(DBG_EVAL, ("pid %d, evaltree(%p: %s(%d), %#x) called\n",
                    getpid(), n, NODETYPENAME(n->type), n->type, flags));
+       /*
                if (n->type != NCMD && traps_invalid)
                        free_traps();
+       */
                switch (n->type) {
                case NSEMI:
                        evaltree(n->nbinary.ch1, sflags);
@@ -302,6 +304,8 @@
                        next = n->nbinary.ch2;
                        break;
                case NREDIR:
+                       if (traps_invalid)
+                               free_traps();
                        evalredir(n, flags);
                        break;
                case NSUBSHELL:
@@ -309,9 +313,13 @@
                        do_etest = !(flags & EV_TESTED);
                        break;
                case NBACKGND:
+                       if (traps_invalid)
+                               free_traps();
                        evalsubshell(n, flags);
                        break;
                case NIF: {
+                       if (traps_invalid)
+                               free_traps();
                        evaltree(n->nif.test, EV_TESTED);
                        if (nflag || evalskip)
                                goto out1;
@@ -325,15 +333,23 @@
                }
                case NWHILE:
                case NUNTIL:
+                       if (traps_invalid)
+                               free_traps();
                        evalloop(n, sflags);
                        break;
                case NFOR:
+                       if (traps_invalid)
+                               free_traps();
                        evalfor(n, sflags);
                        break;
                case NCASE:
+                       if (traps_invalid)
+                               free_traps();
                        evalcase(n, sflags);
                        break;
                case NDEFUN:
+                       if (traps_invalid)
+                               free_traps();
                        CTRACE(DBG_EVAL, ("Defining fn %s @%d%s\n",
                            n->narg.text, n->narg.lineno,
                            fnline1 ? " LINENO=1" : ""));
@@ -350,6 +366,8 @@
                                exitstatus = 1;
                        break;
                case NPIPE:
+                       if (traps_invalid)
+                               free_traps();
                        evalpipe(n);
                        do_etest = !(flags & EV_TESTED);
                        break;
@@ -1043,6 +1061,10 @@
         *      command eval trap
         *      eval command trap
         * 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
         * back here again, the "anything" will be validated.
@@ -1055,6 +1077,7 @@
         * trapcmd() takes care of doing free_traps() if it is needed there.
         */
        if (traps_invalid &&
+           cmdentry.cmdtype != CMDFUNCTION &&
            ((cmdentry.cmdtype!=CMDSPLBLTIN && cmdentry.cmdtype!=CMDBUILTIN) ||
             (cmdentry.u.bltin != trapcmd && cmdentry.u.bltin != evalcmd)))
                free_traps();
diff -r 9dc686dd8f1d -r 63e9cc5ce233 bin/sh/trap.c
--- a/bin/sh/trap.c     Thu Aug 20 23:03:17 2020 +0000
+++ b/bin/sh/trap.c     Thu Aug 20 23:09:56 2020 +0000
@@ -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
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)trap.c     8.5 (Berkeley) 6/5/95";
 #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 /* not lint */
 
@@ -232,6 +232,8 @@
        ap = argv + 1;
 
        CTRACE(DBG_TRAP, ("trapcmd: "));
+       if (argc == 3 && strcmp(ap[1], "--") == 0)
+               argc--;
        if (argc == 2 && strcmp(*ap, "-l") == 0) {
                CTRACE(DBG_TRAP, ("-l\n"));
                out1str("EXIT");
@@ -253,9 +255,9 @@
                traps_invalid = 0;
                return 0;
        }
-       if (argc >= 2 && strcmp(*ap, "-p") == 0) {
-               CTRACE(DBG_TRAP, ("-p "));
-               printonly = 1;
+       if (argc >= 2 && (strcmp(*ap, "-p") == 0 || strcmp(*ap, "-P") == 0)) {
+               CTRACE(DBG_TRAP, ("%s ", *ap));
+               printonly = 1 + (ap[0][1] == 'p');
                ap++;
                argc--;
        }
@@ -265,6 +267,9 @@
                ap++;
        }
 
+       if (printonly == 1 && argc < 2)
+               goto usage;
+
        if (argc <= 1) {
                int count;
 
@@ -339,8 +344,10 @@
        }
 
        if (argc < 2) {         /* there must be at least 1 condition */
+ usage:
                out2str("Usage: trap [-l]\n"
                        "       trap -p [condition ...]\n"
+                       "       trap -P  condition ...\n"
                        "       trap action condition ...\n"
                        "       trap N condition ...\n");
                return 2;
@@ -365,12 +372,17 @@
                         * (action will always be "-") here, if someone
                         * really wants to get that particular output
                         */
-                       out1str("trap -- ");
-                       if (trap[signo] == NULL)
-                               out1str("-");
-                       else
-                               print_quoted(trap[signo]);
-                       out1fmt(" %s\n", trap_signame(signo));
+                       if (printonly == 1) {
+                               if (trap[signo] != NULL)
+                                       out1fmt("%s\n", trap[signo]);
+                       } else {
+                               out1str("trap -- ");
+                               if (trap[signo] == NULL)
+                                       out1str("-");
+                               else
+                                       print_quoted(trap[signo]);
+                               out1fmt(" %s\n", trap_signame(signo));
+                       }
                        continue;
                }
 



Home | Main Index | Thread Index | Old Index