aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-12-15 15:01:53 +0000
committerRon Yorston <rmy@pobox.com>2018-12-15 15:39:28 +0000
commit65189dacb44708743313c81ec1ccaff87a68be8d (patch)
treeb1330575c61bce5adc7d5be815490ac7cb431852 /shell
parenta236242374daf911a01e998fabb1cc1268b2be7b (diff)
downloadbusybox-w32-65189dacb44708743313c81ec1ccaff87a68be8d.tar.gz
busybox-w32-65189dacb44708743313c81ec1ccaff87a68be8d.tar.bz2
busybox-w32-65189dacb44708743313c81ec1ccaff87a68be8d.zip
ash: fix local PATH assignments
The previous commit included code to use PATH values assigned to local variables: PATH=/new/path:$PATH new_binary It didn't work in the case when no fork was needed, for example: (PATH=/new/path:$PATH new_binary) because the call to listsetvar() freed the PATH value that was passed to shellexec(). The forking case only worked because the spawn_forkshell() mechanism in busybox-w32 didn't allow the PATH value to be freed. Rewrite the code so it works whether or not a fork is needed. The code would also work on POSIX systems. A cleaner solution could be extracted from dash commit cbb71a8 'eval: Add assignment built-in support again' but neither that nor the current patch are suitable for submission to upstream BusyBox. This one is preferred because it requires fewer changes from upstream.
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/shell/ash.c b/shell/ash.c
index a659fd703..5195a8557 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -10531,6 +10531,9 @@ evalcommand(union node *cmd, int flags)
10531 int status; 10531 int status;
10532 char **nargv; 10532 char **nargv;
10533 smallint cmd_is_exec; 10533 smallint cmd_is_exec;
10534#if ENABLE_PLATFORM_MINGW32
10535 int cmdpath;
10536#endif
10534 10537
10535 errlinno = lineno = cmd->ncmd.linno; 10538 errlinno = lineno = cmd->ncmd.linno;
10536 if (funcline) 10539 if (funcline)
@@ -10599,6 +10602,7 @@ evalcommand(union node *cmd, int flags)
10599 } 10602 }
10600 status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2); 10603 status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
10601 10604
10605#if !ENABLE_PLATFORM_MINGW32
10602 path = vpath.var_text; 10606 path = vpath.var_text;
10603 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) { 10607 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
10604 struct strlist **spp; 10608 struct strlist **spp;
@@ -10615,14 +10619,17 @@ evalcommand(union node *cmd, int flags)
10615 */ 10619 */
10616 p = (*spp)->text; 10620 p = (*spp)->text;
10617 if (varcmp(p, path) == 0) 10621 if (varcmp(p, path) == 0)
10618#if !ENABLE_PLATFORM_MINGW32
10619 path = p; 10622 path = p;
10623 }
10620#else 10624#else
10621 /* fix_pathvar may have modified the value of the local 10625 /* Set path after any local PATH= has been processed. */
10622 * variable so we look it up again */ 10626 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
10623 path = vpath.var_text; 10627 struct strlist **spp = varlist.lastp;
10624#endif 10628 expandarg(argp, &varlist, EXP_VARTILDE);
10629 mklocal((*spp)->text);
10625 } 10630 }
10631 path = vpath.var_text;
10632#endif
10626 10633
10627 /* Print the command if xflag is set. */ 10634 /* Print the command if xflag is set. */
10628 if (xflag) { 10635 if (xflag) {
@@ -10780,7 +10787,13 @@ evalcommand(union node *cmd, int flags)
10780 TRACE(("forked child exited with %d\n", status)); 10787 TRACE(("forked child exited with %d\n", status));
10781 break; 10788 break;
10782 } 10789 }
10783 /* goes through to shellexec() */ 10790 /* If we're running 'command -p' we need to use the value stored
10791 * in path by parse_command_args(). If PATH is a local variable
10792 * listsetvar() will free the value currently in path so we need
10793 * to fetch the updated version. */
10794 cmdpath = (path != pathval());
10795 listsetvar(varlist.list, VEXPORT|VSTACK);
10796 shellexec(argv[0], argv, cmdpath ? path : pathval(), cmdentry.u.index);
10784#else 10797#else
10785 if (!(flags & EV_EXIT) || may_have_traps) { 10798 if (!(flags & EV_EXIT) || may_have_traps) {
10786 /* No, forking off a child is necessary */ 10799 /* No, forking off a child is necessary */
@@ -10798,9 +10811,9 @@ evalcommand(union node *cmd, int flags)
10798 FORCE_INT_ON; 10811 FORCE_INT_ON;
10799 /* fall through to exec'ing external program */ 10812 /* fall through to exec'ing external program */
10800 } 10813 }
10801#endif
10802 listsetvar(varlist.list, VEXPORT|VSTACK); 10814 listsetvar(varlist.list, VEXPORT|VSTACK);
10803 shellexec(argv[0], argv, path, cmdentry.u.index); 10815 shellexec(argv[0], argv, path, cmdentry.u.index);
10816#endif
10804 /* NOTREACHED */ 10817 /* NOTREACHED */
10805 } /* default */ 10818 } /* default */
10806 case CMDBUILTIN: 10819 case CMDBUILTIN: