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