aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-03-30 11:05:04 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2023-03-31 14:22:56 +0200
commit098cd7ece44bf7ab7ae38dc00dd574af79a9bad8 (patch)
treeaf16f7162dc6a5bbcea8277528476859325d4cb7
parentaf5277f883e8fc2e0236aa9ecc5115ecaffd0ccb (diff)
downloadbusybox-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.c13
-rw-r--r--shell/ash_test/ash-signals/usage.right12
-rwxr-xr-xshell/ash_test/ash-signals/usage.tests12
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
6trap -- 'a' USR1 6trap -- 'a' USR1
7trap -- 'a' USR2 7trap -- 'a' USR2
8___ 8___
9trap -- 'a' EXIT trap -- 'a' INT trap -- 'a' USR1 trap -- 'a' USR2
10___
11trap -- 'a' EXIT
12trap -- 'a' INT
13trap -- 'a' USR1
14trap -- 'a' USR2
15___
16trap -- 'a' EXIT
17trap -- 'a' INT
18trap -- 'a' USR1
19trap -- 'a' USR2
20___
9___ 21___
10trap -- 'a' USR1 22trap -- 'a' USR1
11trap -- 'a' USR2 23trap -- '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
10echo ___ 10echo ___
11trap 11trap
12 12
13# show them by command substitution
14echo ___
15echo $(trap)
16
17# show them by pipe
18echo ___
19trap | cat
20
21# show them by process substitution
22echo ___
23cat <(trap)
24
13# clear one 25# clear one
14echo ___ 26echo ___
15trap 0 INT 27trap 0 INT