diff options
author | Ron Yorston <rmy@pobox.com> | 2023-03-30 11:05:04 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-03-31 14:22:56 +0200 |
commit | 098cd7ece44bf7ab7ae38dc00dd574af79a9bad8 (patch) | |
tree | af16f7162dc6a5bbcea8277528476859325d4cb7 | |
parent | af5277f883e8fc2e0236aa9ecc5115ecaffd0ccb (diff) | |
download | busybox-w32-098cd7ece44bf7ab7ae38dc00dd574af79a9bad8.tar.gz busybox-w32-098cd7ece44bf7ab7ae38dc00dd574af79a9bad8.tar.bz2 busybox-w32-098cd7ece44bf7ab7ae38dc00dd574af79a9bad8.zip |
ash: improve trap and jobs builtins in child shells
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 <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/ash.c | 13 | ||||
-rw-r--r-- | shell/ash_test/ash-signals/usage.right | 12 | ||||
-rwxr-xr-x | 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) | |||
5190 | 5190 | ||
5191 | closescript(); | 5191 | closescript(); |
5192 | 5192 | ||
5193 | if (mode == FORK_NOJOB /* is it `xxx` ? */ | 5193 | if (n && n->type == NCMD /* is it single cmd? */ |
5194 | && n && n->type == NCMD /* is it single cmd? */ | ||
5195 | /* && n->ncmd.args->type == NARG - always true? */ | 5194 | /* && n->ncmd.args->type == NARG - always true? */ |
5196 | && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0 | 5195 | && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0 |
5197 | && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */ | 5196 | && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */ |
@@ -5285,10 +5284,12 @@ forkchild(struct job *jp, union node *n, int mode) | |||
5285 | ) { | 5284 | ) { |
5286 | TRACE(("Job hack\n")); | 5285 | TRACE(("Job hack\n")); |
5287 | /* "jobs": we do not want to clear job list for it, | 5286 | /* "jobs": we do not want to clear job list for it, |
5288 | * instead we remove only _its_ own_ job from job list. | 5287 | * instead we remove only _its_ own_ job from job list |
5288 | * (if it has one). | ||
5289 | * This makes "jobs .... | cat" more useful. | 5289 | * This makes "jobs .... | cat" more useful. |
5290 | */ | 5290 | */ |
5291 | freejob(curjob); | 5291 | if (jp) |
5292 | freejob(curjob); | ||
5292 | return; | 5293 | return; |
5293 | } | 5294 | } |
5294 | #endif | 5295 | #endif |
@@ -6607,9 +6608,9 @@ evalbackcmd(union node *n, struct backcmd *result | |||
6607 | 6608 | ||
6608 | if (pipe(pip) < 0) | 6609 | if (pipe(pip) < 0) |
6609 | ash_msg_and_raise_perror("can't create pipe"); | 6610 | ash_msg_and_raise_perror("can't create pipe"); |
6610 | /* process substitution uses NULL job/node, like openhere() */ | 6611 | /* process substitution uses NULL job, like openhere() */ |
6611 | jp = (ctl == CTLBACKQ) ? makejob(/*n,*/ 1) : NULL; | 6612 | jp = (ctl == CTLBACKQ) ? makejob(/*n,*/ 1) : NULL; |
6612 | if (forkshell(jp, (ctl == CTLBACKQ) ? n : NULL, FORK_NOJOB) == 0) { | 6613 | if (forkshell(jp, n, FORK_NOJOB) == 0) { |
6613 | /* child */ | 6614 | /* child */ |
6614 | FORCE_INT_ON; | 6615 | FORCE_INT_ON; |
6615 | close(pip[ip]); | 6616 | 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 | |||
6 | trap -- 'a' USR1 | 6 | trap -- 'a' USR1 |
7 | trap -- 'a' USR2 | 7 | trap -- 'a' USR2 |
8 | ___ | 8 | ___ |
9 | trap -- 'a' EXIT trap -- 'a' INT trap -- 'a' USR1 trap -- 'a' USR2 | ||
10 | ___ | ||
11 | trap -- 'a' EXIT | ||
12 | trap -- 'a' INT | ||
13 | trap -- 'a' USR1 | ||
14 | trap -- 'a' USR2 | ||
15 | ___ | ||
16 | trap -- 'a' EXIT | ||
17 | trap -- 'a' INT | ||
18 | trap -- 'a' USR1 | ||
19 | trap -- 'a' USR2 | ||
20 | ___ | ||
9 | ___ | 21 | ___ |
10 | trap -- 'a' USR1 | 22 | trap -- 'a' USR1 |
11 | trap -- 'a' USR2 | 23 | 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 | |||
10 | echo ___ | 10 | echo ___ |
11 | trap | 11 | trap |
12 | 12 | ||
13 | # show them by command substitution | ||
14 | echo ___ | ||
15 | echo $(trap) | ||
16 | |||
17 | # show them by pipe | ||
18 | echo ___ | ||
19 | trap | cat | ||
20 | |||
21 | # show them by process substitution | ||
22 | echo ___ | ||
23 | cat <(trap) | ||
24 | |||
13 | # clear one | 25 | # clear one |
14 | echo ___ | 26 | echo ___ |
15 | trap 0 INT | 27 | trap 0 INT |