Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Mar 1997 06:10:05 -0800 (PST)
From:      Gareth McCaughan <gjm11@dpmms.cam.ac.uk>
To:        freebsd-bugs
Subject:   Re: bin/2934: sh(1) has problems with $ENV 
Message-ID:  <199703111410.GAA05094@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/2934; it has been noted by GNATS.

From: Gareth McCaughan <gjm11@dpmms.cam.ac.uk>
To: freebsd-bugs@freebsd.org
Cc:  Subject: Re: bin/2934: sh(1) has problems with $ENV 
Date: Tue, 11 Mar 1997 12:53:06 +0000

 > >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.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703111410.GAA05094>