Fix command hash handling on
PATH=... command Noted by and fix works for Marcel Moolenaar <marcel@scc.nl>
This commit is contained in:
parent
97b45ce9c3
commit
a436dc79f5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=54884
@ -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 @@ evalcommand(cmd, flags, backcmd)
|
||||
out:
|
||||
if (lastarg)
|
||||
setvar("_", lastarg, 0);
|
||||
if (do_clearcmdentry)
|
||||
clearcmdentry(0);
|
||||
popstackmark(&smark);
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,6 @@ STATIC void tryexec __P((char *, char **, char **));
|
||||
STATIC void execinterp __P((char **, char **));
|
||||
#endif
|
||||
STATIC void printentry __P((struct tblentry *, int));
|
||||
STATIC void clearcmdentry __P((int));
|
||||
STATIC struct tblentry *cmdlookup __P((char *, int));
|
||||
STATIC void delete_cmd_entry __P((void));
|
||||
|
||||
@ -640,7 +639,7 @@ changepath(newval)
|
||||
* PATH which has changed.
|
||||
*/
|
||||
|
||||
STATIC void
|
||||
void
|
||||
clearcmdentry(firstchange)
|
||||
int firstchange;
|
||||
{
|
||||
|
@ -69,3 +69,4 @@ void addcmdentry __P((char *, struct cmdentry *));
|
||||
void defun __P((char *, union node *));
|
||||
int unsetfunc __P((char *));
|
||||
int typecmd __P((int, char **));
|
||||
void clearcmdentry __P((int));
|
||||
|
Loading…
Reference in New Issue
Block a user