summaryrefslogtreecommitdiffstats
path: root/bin/sh/eval.c
diff options
context:
space:
mode:
authorcracauer <cracauer@FreeBSD.org>1999-12-20 13:42:59 +0000
committercracauer <cracauer@FreeBSD.org>1999-12-20 13:42:59 +0000
commit6d35bd2d53c6a7ddb80ecae5e0148a58c23b73e6 (patch)
tree82531f32187fe6780dd6491e283a806a71a99d0d /bin/sh/eval.c
parentb4682bef656f35db2ebb8df88d935e6042aa97f0 (diff)
downloadFreeBSD-src-6d35bd2d53c6a7ddb80ecae5e0148a58c23b73e6.zip
FreeBSD-src-6d35bd2d53c6a7ddb80ecae5e0148a58c23b73e6.tar.gz
Fix command hash handling on
PATH=... command Noted by and fix works for Marcel Moolenaar <marcel@scc.nl>
Diffstat (limited to 'bin/sh/eval.c')
-rw-r--r--bin/sh/eval.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 4f20822..33dec0e 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -612,12 +612,14 @@ evalcommand(cmd, flags, backcmd)
volatile int e;
char *lastarg;
int realstatus;
+ int do_clearcmdentry;
#if __GNUC__
/* Avoid longjmp clobbering */
(void) &argv;
(void) &argc;
(void) &lastarg;
(void) &flags;
+ (void) &do_clearcmdentry;
#endif
/* First expand the arguments. */
@@ -626,6 +628,7 @@ evalcommand(cmd, flags, backcmd)
arglist.lastp = &arglist.list;
varlist.lastp = &varlist.list;
varflag = 1;
+ do_clearcmdentry = 0;
oexitstatus = exitstatus;
exitstatus = 0;
for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) {
@@ -688,8 +691,29 @@ evalcommand(cmd, flags, backcmd)
* is present
*/
for (sp = varlist.list ; sp ; sp = sp->next)
- if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0)
+ if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) {
path = sp->text + sizeof(PATH) - 1;
+ /*
+ * On `PATH=... command`, we need to make
+ * sure that the command isn't using the
+ * non-updated hash table of the outer PATH
+ * setting and we need to make sure that
+ * the hash table isn't filled with items
+ * from the temporary setting.
+ *
+ * It would be better to forbit using and
+ * updating the table while this command
+ * runs, by the command finding mechanism
+ * is heavily integrated with hash handling,
+ * so we just delete the hash before and after
+ * the command runs. Partly deleting like
+ * changepatch() does doesn't seem worth the
+ * bookinging effort, since most such runs add
+ * diretories in front of the new PATH.
+ */
+ clearcmdentry(0);
+ do_clearcmdentry = 1;
+ }
find_command(argv[0], &cmdentry, 1, path);
if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
@@ -887,6 +911,8 @@ parent: /* parent process gets here (if we forked) */
out:
if (lastarg)
setvar("_", lastarg, 0);
+ if (do_clearcmdentry)
+ clearcmdentry(0);
popstackmark(&smark);
}
OpenPOWER on IntegriCloud