Date: Tue, 11 Mar 1997 12:53:06 +0000 From: Gareth McCaughan <gjm11@dpmms.cam.ac.uk> To: freebsd-bugs@freebsd.org Subject: Re: bin/2934: sh(1) has problems with $ENV Message-ID: <E0w4R3C-0001Np-00@g.pet.cam.ac.uk> In-Reply-To: Your message of "Tue, 11 Mar 1997 00:55:56 %2B0100." <199703102355.AAA10899@uriah.heep.sax.de>
index | next in thread | previous in thread | raw e-mail
> >Description:
>
> /bin/sh processes $ENV fine if it has been set inside ~/.profile like:
>
> ENV=${HOME}/.env; export ENV
>
> However, it fails to source $ENV in this case:
>
> export ENV=${HOME}/.env
This is not quite correct. If you use this idiom, sh behaves
correctly. If, however, you use ~ instead of $HOME, then the
tilde doesn't get expanded when you do "export ENV=~/foo",
but it does when you do "ENV=~/foo".
Then, when your new sh starts up and reads ENV, it finds the
variable correctly in both cases; however, its ENV-processing
code doesn't interpret the ~ and so it fails to find the file.
My reading of the sh(1) manpage is that tilde expansion *should*
happen, and that the ENV-processing code *should not* try to
do tilde expansion, but I am no sh(1) guru so I speak subject
to correction.
If my reading is correct, then (1) the same problem also affects
the "readonly" command, and (2) I believe that the following patch
fixes both problems. (It's relative to the version of sh in 2.2-GAMMA.)
I repeat that I am not a sh(1) guru, so this ought to be checked
by someone who knows more than I do about this stuff. I've moved
the "locate command" code so that it happens as soon as it's known
what the command is; then, if the command is "export" or "readonly",
the args are expanded like initial var=val pairs are.
---------- patch begins ----------
*** eval.c.orig Tue Nov 12 19:23:44 1996
--- eval.c Tue Mar 11 12:47:04 1997
***************
*** 594,600 ****
char **argv;
int argc;
char **envp;
! int varflag;
struct strlist *sp;
int mode;
int pip[2];
--- 594,600 ----
char **argv;
int argc;
char **envp;
! int doing_cmd, setting_cmd;
struct strlist *sp;
int mode;
int pip[2];
***************
*** 607,612 ****
--- 607,613 ----
struct localvar *volatile savelocalvars;
volatile int e;
char *lastarg;
+ char *path=pathval();
#if __GNUC__
/* Avoid longjmp clobbering */
(void) &argv;
***************
*** 620,641 ****
setstackmark(&smark);
arglist.lastp = &arglist.list;
varlist.lastp = &varlist.list;
! varflag = 1;
oexitstatus = exitstatus;
exitstatus = 0;
for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) {
char *p = argp->narg.text;
! if (varflag && is_name(*p)) {
do {
p++;
} while (is_in_name(*p));
! if (*p == '=') {
! expandarg(argp, &varlist, EXP_VARTILDE);
continue;
}
}
! expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
! varflag = 0;
}
*arglist.lastp = NULL;
*varlist.lastp = NULL;
--- 621,660 ----
setstackmark(&smark);
arglist.lastp = &arglist.list;
varlist.lastp = &varlist.list;
! doing_cmd = 1; setting_cmd = 0;
oexitstatus = exitstatus;
exitstatus = 0;
for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) {
char *p = argp->narg.text;
! if ((doing_cmd || setting_cmd) && is_name(*p)) {
do {
p++;
} while (is_in_name(*p));
! if (*p == '=') {
! expandarg(argp,
! setting_cmd ? &arglist : &varlist,
! EXP_VARTILDE);
! if (doing_cmd) {
! static const char PATH[] = "PATH=";
! char *s = ((struct strlist *)varlist.lastp)->text;
! if (!strncmp(s, PATH, sizeof(PATH)-1))
! path = s + sizeof(PATH) - 1;
! }
continue;
}
}
! {
! expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
! if (doing_cmd) {
! char *s = ((struct strlist *)arglist.lastp)->text;
! /* Now locate the command. */
! find_command(s, &cmdentry, 1, path);
! /* Does it require us to grok future var=val pairs? */
! if (cmdentry.cmdtype == CMDBUILTIN && cmdentry.u.index == EXPORTCMD)
! setting_cmd=1;
! }
! doing_cmd = 0;
! }
}
*arglist.lastp = NULL;
*varlist.lastp = NULL;
***************
*** 675,692 ****
cmdentry.cmdtype = CMDBUILTIN;
cmdentry.u.index = BLTINCMD;
} else {
- static const char PATH[] = "PATH=";
- char *path = pathval();
-
- /*
- * Modify the command lookup path, if a PATH= assignment
- * is present
- */
- for (sp = varlist.list ; sp ; sp = sp->next)
- if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0)
- path = sp->text + sizeof(PATH) - 1;
-
- find_command(argv[0], &cmdentry, 1, path);
if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
exitstatus = 1;
flushout(&errout);
--- 694,699 ----
----------- patch ends -----------
--
Gareth McCaughan Dept. of Pure Mathematics & Mathematical Statistics,
gjm11@dpmms.cam.ac.uk Cambridge University, England.
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?E0w4R3C-0001Np-00>
