diff options
author | Ron Yorston <rmy@pobox.com> | 2023-03-28 13:06:56 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-03-28 13:06:56 +0100 |
commit | 5ead1485640c81d0b020768d59a32d9029a164ee (patch) | |
tree | 3d77f6ac68c8f793eef4bfd5a781ed92d9630b3d /shell | |
parent | 255ebaf535c9f6d8a88e23d55d8be04b0ea73343 (diff) | |
download | busybox-w32-5ead1485640c81d0b020768d59a32d9029a164ee.tar.gz busybox-w32-5ead1485640c81d0b020768d59a32d9029a164ee.tar.bz2 busybox-w32-5ead1485640c81d0b020768d59a32d9029a164ee.zip |
ash: changes to evalsubshell()
When a spawn_forkshell() was required in evalsubshell() two calls
to expredir() were being made: one in the parent and one in the
child. Rearrange the code so there's only one call, in the child.
The call to expredir() in the child is necessary because copynode()
doesn't take a copy of expfname in the nfile node. Code could be
added to do this but it's cheaper to call expredir().
Add code in forkshell_evalsubshell() to turn off the EV_TESTED
flag for background processes. I haven't found a case where this
makes a difference but no doubt somebody would have eventually.
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/shell/ash.c b/shell/ash.c index 1eddec4ea..913f0ce22 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -10473,9 +10473,18 @@ evalsubshell(union node *n, int flags) | |||
10473 | 10473 | ||
10474 | errlinno = lineno = n->nredir.linno; | 10474 | errlinno = lineno = n->nredir.linno; |
10475 | 10475 | ||
10476 | #if ENABLE_PLATFORM_MINGW32 | ||
10477 | if (!backgnd && (flags & EV_EXIT) && !may_have_traps) { | ||
10478 | expredir(n->nredir.redirect); | ||
10479 | redirect(n->nredir.redirect, 0); | ||
10480 | evaltreenr(n->nredir.n, flags); | ||
10481 | /* never returns */ | ||
10482 | } | ||
10483 | #else | ||
10476 | expredir(n->nredir.redirect); | 10484 | expredir(n->nredir.redirect); |
10477 | if (!backgnd && (flags & EV_EXIT) && !may_have_traps) | 10485 | if (!backgnd && (flags & EV_EXIT) && !may_have_traps) |
10478 | goto nofork; | 10486 | goto nofork; |
10487 | #endif | ||
10479 | INT_OFF; | 10488 | INT_OFF; |
10480 | if (backgnd == FORK_FG) | 10489 | if (backgnd == FORK_FG) |
10481 | get_tty_state(); | 10490 | get_tty_state(); |
@@ -10486,7 +10495,6 @@ evalsubshell(union node *n, int flags) | |||
10486 | fs.n = n; | 10495 | fs.n = n; |
10487 | fs.flags = flags; | 10496 | fs.flags = flags; |
10488 | spawn_forkshell(&fs, jp, n, backgnd); | 10497 | spawn_forkshell(&fs, jp, n, backgnd); |
10489 | if ( 0 ) { | ||
10490 | #else | 10498 | #else |
10491 | if (forkshell(jp, n, backgnd) == 0) { | 10499 | if (forkshell(jp, n, backgnd) == 0) { |
10492 | /* child */ | 10500 | /* child */ |
@@ -10494,12 +10502,12 @@ evalsubshell(union node *n, int flags) | |||
10494 | flags |= EV_EXIT; | 10502 | flags |= EV_EXIT; |
10495 | if (backgnd) | 10503 | if (backgnd) |
10496 | flags &= ~EV_TESTED; | 10504 | flags &= ~EV_TESTED; |
10497 | #endif | ||
10498 | nofork: | 10505 | nofork: |
10499 | redirect(n->nredir.redirect, 0); | 10506 | redirect(n->nredir.redirect, 0); |
10500 | evaltreenr(n->nredir.n, flags); | 10507 | evaltreenr(n->nredir.n, flags); |
10501 | /* never returns */ | 10508 | /* never returns */ |
10502 | } | 10509 | } |
10510 | #endif | ||
10503 | /* parent */ | 10511 | /* parent */ |
10504 | status = 0; | 10512 | status = 0; |
10505 | if (backgnd == FORK_FG) | 10513 | if (backgnd == FORK_FG) |
@@ -16114,6 +16122,8 @@ forkshell_evalsubshell(struct forkshell *fs) | |||
16114 | TRACE(("ash: subshell: %s\n",__PRETTY_FUNCTION__)); | 16122 | TRACE(("ash: subshell: %s\n",__PRETTY_FUNCTION__)); |
16115 | INT_ON; | 16123 | INT_ON; |
16116 | flags |= EV_EXIT; | 16124 | flags |= EV_EXIT; |
16125 | if (fs->mode) | ||
16126 | flags &= ~EV_TESTED; | ||
16117 | expredir(n->nredir.redirect); | 16127 | expredir(n->nredir.redirect); |
16118 | redirect(n->nredir.redirect, 0); | 16128 | redirect(n->nredir.redirect, 0); |
16119 | evaltreenr(n->nredir.n, flags); | 16129 | evaltreenr(n->nredir.n, flags); |