summaryrefslogtreecommitdiff
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.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];