about summary refs log tree commit diff
path: root/Src/exec.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2009-02-11 20:42:15 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2009-02-11 20:42:15 +0000
commitc7d8b0dfb8ae9670e2bc11ecf563200069a3a12f (patch)
tree822403086b3d6d77bb14846b6e286d59389da12c /Src/exec.c
parent0d02cf343eda943c32f7edfd24f28dbbd7004e32 (diff)
downloadzsh-c7d8b0dfb8ae9670e2bc11ecf563200069a3a12f.tar.gz
zsh-c7d8b0dfb8ae9670e2bc11ecf563200069a3a12f.tar.xz
zsh-c7d8b0dfb8ae9670e2bc11ecf563200069a3a12f.zip
26546, 26556: sticky emulation for functions defined in emulate ... -c ...
environments, plus documentation
Diffstat (limited to 'Src/exec.c')
-rw-r--r--Src/exec.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/Src/exec.c b/Src/exec.c
index 5aec655a2..b86e5350c 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -3999,6 +3999,7 @@ execfuncdef(Estate state, UNUSED(int do_exec))
 	shf->node.flags = 0;
 	shf->filename = ztrdup(scriptfilename);
 	shf->lineno = lineno;
+	shf->emulation = sticky_emulation;
 
 	if (!names) {
 	    /*
@@ -4221,7 +4222,7 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
     char *name = shfunc->node.nam;
     int flags = shfunc->node.flags;
     char *fname = dupstring(name);
-    int obreaks, saveemulation ;
+    int obreaks, saveemulation, savesticky_emulation, restore_sticky;
     Eprog prog;
     struct funcstack fstack;
 #ifdef MAX_FUNCTION_DEPTH
@@ -4261,6 +4262,26 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
      * function we need to restore the original options on exit.   */
     memcpy(saveopts, opts, sizeof(opts));
     saveemulation = emulation;
+    savesticky_emulation = sticky_emulation;
+
+    if (shfunc->emulation && sticky_emulation != shfunc->emulation) {
+	/*
+	 * Function is marked for sticky emulation.
+	 * Enable it now.
+	 *
+	 * We deliberately do not do this if the sticky emulation
+	 * in effect is the same as that requested.  This enables
+	 * option setting naturally within emulation environments.
+	 * Note that a difference in EMULATE_FULLY (emulate with
+	 * or without -R) counts as a different environment.
+	 *
+	 * This propagates the sticky emulation to subfunctions.
+	 */
+	emulation = sticky_emulation = shfunc->emulation;
+	restore_sticky = 1;
+	installemulation();
+    } else
+	restore_sticky = 0;
 
     if (flags & PM_TAGGED)
 	opts[XTRACE] = 1;
@@ -4349,7 +4370,16 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
     zoptind = oldzoptind;
     scriptname = oldscriptname;
 
-    if (isset(LOCALOPTIONS)) {
+    if (restore_sticky) {
+	/*
+	 * If we switched to an emulation environment just for
+	 * this function, we interpret the option and emulation
+	 * switch as being a firewall between environments.
+	 */
+	memcpy(opts, saveopts, sizeof(opts));
+	emulation = saveemulation;
+	sticky_emulation = savesticky_emulation;
+    } else if (isset(LOCALOPTIONS)) {
 	/* restore all shell options except PRIVILEGED and RESTRICTED */
 	saveopts[PRIVILEGED] = opts[PRIVILEGED];
 	saveopts[RESTRICTED] = opts[RESTRICTED];