The trap and jobs builtins can be used to report information about
traps and jobs.  This works when they're called from the current
shell but in a child shell the required information is usually
cleared.  Special hacks allow:

- trap to work with command substitution;
- jobs to work with command substitution or in a pipeline.

Neither works with process substitution.

- Relax the test for the trap hack so it also supports pipelines.

- Pass the command to be evaluated to forkshell() in evalbackcmd()
  so trap and jobs both work with process substitution.

function                                             old     new   delta
forkchild                                            629     640     +11
argstr                                              1502    1496      -6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 11/-6)               Total: 5 bytes

Signed-off-by: Ron Yorston <[email protected]>
---
 shell/ash.c                            | 13 +++++++------
 shell/ash_test/ash-signals/usage.right | 12 ++++++++++++
 shell/ash_test/ash-signals/usage.tests | 12 ++++++++++++
 3 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index 559566b58..40b921be1 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -5190,8 +5190,7 @@ forkchild(struct job *jp, union node *n, int mode)
 
        closescript();
 
-       if (mode == FORK_NOJOB          /* is it `xxx` ? */
-        && n && n->type == NCMD        /* is it single cmd? */
+       if (n && n->type == NCMD        /* is it single cmd? */
        /* && n->ncmd.args->type == NARG - always true? */
         && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0
         && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */
@@ -5285,10 +5284,12 @@ forkchild(struct job *jp, union node *n, int mode)
        ) {
                TRACE(("Job hack\n"));
                /* "jobs": we do not want to clear job list for it,
-                * instead we remove only _its_ own_ job from job list.
+                * instead we remove only _its_ own_ job from job list
+                * (if it has one).
                 * This makes "jobs .... | cat" more useful.
                 */
-               freejob(curjob);
+               if (jp)
+                       freejob(curjob);
                return;
        }
 #endif
@@ -6607,9 +6608,9 @@ evalbackcmd(union node *n, struct backcmd *result
 
        if (pipe(pip) < 0)
                ash_msg_and_raise_perror("can't create pipe");
-       /* process substitution uses NULL job/node, like openhere() */
+       /* process substitution uses NULL job, like openhere() */
        jp = (ctl == CTLBACKQ) ? makejob(/*n,*/ 1) : NULL;
-       if (forkshell(jp, (ctl == CTLBACKQ) ? n : NULL, FORK_NOJOB) == 0) {
+       if (forkshell(jp, n, FORK_NOJOB) == 0) {
                /* child */
                FORCE_INT_ON;
                close(pip[ip]);
diff --git a/shell/ash_test/ash-signals/usage.right 
b/shell/ash_test/ash-signals/usage.right
index c0dbd6c3c..df1ed2dd7 100644
--- a/shell/ash_test/ash-signals/usage.right
+++ b/shell/ash_test/ash-signals/usage.right
@@ -6,6 +6,18 @@ trap -- 'a' INT
 trap -- 'a' USR1
 trap -- 'a' USR2
 ___
+trap -- 'a' EXIT trap -- 'a' INT trap -- 'a' USR1 trap -- 'a' USR2
+___
+trap -- 'a' EXIT
+trap -- 'a' INT
+trap -- 'a' USR1
+trap -- 'a' USR2
+___
+trap -- 'a' EXIT
+trap -- 'a' INT
+trap -- 'a' USR1
+trap -- 'a' USR2
+___
 ___
 trap -- 'a' USR1
 trap -- 'a' USR2
diff --git a/shell/ash_test/ash-signals/usage.tests 
b/shell/ash_test/ash-signals/usage.tests
index d29c6e74a..34e24cceb 100755
--- a/shell/ash_test/ash-signals/usage.tests
+++ b/shell/ash_test/ash-signals/usage.tests
@@ -10,6 +10,18 @@ trap "a" EXIT INT USR1 USR2
 echo ___
 trap
 
+# show them by command substitution
+echo ___
+echo $(trap)
+
+# show them by pipe
+echo ___
+trap | cat
+
+# show them by process substitution
+echo ___
+cat <(trap)
+
 # clear one
 echo ___
 trap 0 INT
-- 
2.39.2

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to