svn commit: r293635 - in head/bin/sh: . tests/builtins

Jilles Tjoelker jilles at FreeBSD.org
Sun Jan 10 16:31:30 UTC 2016


Author: jilles
Date: Sun Jan 10 16:31:28 2016
New Revision: 293635
URL: https://svnweb.freebsd.org/changeset/base/293635

Log:
  sh: Update associated state when restoring locals while leaving a function.
  
  Some variables like PATH call a function when modified. Make sure to call
  this also when leaving a function where such a variable was made local.
  
  Make sure to restore local variables before shellparam, so getopts state is
  not clobbered.

Added:
  head/bin/sh/tests/builtins/local5.0   (contents, props changed)
Modified:
  head/bin/sh/eval.c
  head/bin/sh/tests/builtins/Makefile
  head/bin/sh/var.c

Modified: head/bin/sh/eval.c
==============================================================================
--- head/bin/sh/eval.c	Sun Jan 10 13:53:57 2016	(r293634)
+++ head/bin/sh/eval.c	Sun Jan 10 16:31:28 2016	(r293635)
@@ -1039,12 +1039,12 @@ evalcommand(union node *cmd, int flags, 
 		reffunc(cmdentry.u.func);
 		savehandler = handler;
 		if (setjmp(jmploc.loc)) {
-			freeparam(&shellparam);
-			shellparam = saveparam;
 			popredir();
 			unreffunc(cmdentry.u.func);
 			poplocalvars();
 			localvars = savelocalvars;
+			freeparam(&shellparam);
+			shellparam = saveparam;
 			funcnest--;
 			handler = savehandler;
 			longjmp(handler->loc, 1);

Modified: head/bin/sh/tests/builtins/Makefile
==============================================================================
--- head/bin/sh/tests/builtins/Makefile	Sun Jan 10 13:53:57 2016	(r293634)
+++ head/bin/sh/tests/builtins/Makefile	Sun Jan 10 16:31:28 2016	(r293635)
@@ -111,6 +111,7 @@ FILES+=		local1.0
 FILES+=		local2.0
 FILES+=		local3.0
 FILES+=		local4.0
+FILES+=		local5.0
 .if ${MK_NLS} != "no"
 FILES+=		locale1.0
 .endif

Added: head/bin/sh/tests/builtins/local5.0
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/bin/sh/tests/builtins/local5.0	Sun Jan 10 16:31:28 2016	(r293635)
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+f() {
+	local PATH IFS elem
+	IFS=:
+	for elem in ''$PATH''; do
+		PATH=/var/empty/$elem:$PATH
+	done
+	ls -d / >/dev/null
+}
+
+p1=$(command -v ls)
+f
+p2=$(command -v ls)
+[ "$p1" = "$p2" ]

Modified: head/bin/sh/var.c
==============================================================================
--- head/bin/sh/var.c	Sun Jan 10 13:53:57 2016	(r293634)
+++ head/bin/sh/var.c	Sun Jan 10 16:31:28 2016	(r293635)
@@ -791,6 +791,7 @@ poplocalvars(void)
 {
 	struct localvar *lvp;
 	struct var *vp;
+	int islocalevar;
 
 	INTOFF;
 	while ((lvp = localvars) != NULL) {
@@ -803,10 +804,20 @@ poplocalvars(void)
 		} else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
 			(void)unsetvar(vp->text);
 		} else {
+			islocalevar = (vp->flags | lvp->flags) & VEXPORT &&
+			    localevar(lvp->text);
 			if ((vp->flags & VTEXTFIXED) == 0)
 				ckfree(vp->text);
 			vp->flags = lvp->flags;
 			vp->text = lvp->text;
+			if (vp->func)
+				(*vp->func)(vp->text + vp->name_len + 1);
+			if (islocalevar) {
+				change_env(vp->text, vp->flags & VEXPORT &&
+				    (vp->flags & VUNSET) == 0);
+				setlocale(LC_ALL, "");
+				updatecharset();
+			}
 		}
 		ckfree(lvp);
 	}


More information about the svn-src-all mailing list