aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
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 /shell/ash.c
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>
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c13
1 files changed, 7 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]);