about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <p.w.stephenson@ntlworld.com>2014-09-29 21:31:37 +0100
committerPeter Stephenson <p.w.stephenson@ntlworld.com>2014-09-29 21:31:37 +0100
commit8cb67e721b3f02779bf4cf0d6a368f67c49c11f8 (patch)
tree851f6234cb2740781dffa876e9e489d87153eb20
parentcf6b0f5663e798c8d4303697115230ac4469baca (diff)
downloadzsh-8cb67e721b3f02779bf4cf0d6a368f67c49c11f8.tar.gz
zsh-8cb67e721b3f02779bf4cf0d6a368f67c49c11f8.tar.xz
zsh-8cb67e721b3f02779bf4cf0d6a368f67c49c11f8.zip
33286: handle redirections for multiply named functions
-rw-r--r--ChangeLog3
-rw-r--r--Src/exec.c17
-rw-r--r--Test/A04redirect.ztst16
3 files changed, 35 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 7fa84fb86..b8bbbdea8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2014-09-29  Peter Stephenson  <p.w.stephenson@ntlworld.com>
 
+	* 33286: Src/exec.c, Test/A04redirect.ztst: handle redirections
+	for multiple named functions.
+
 	* 33285: NEWS, Src/exec.c, Src/hashtable.c, Src/parse.c,
 	Src/signals.c, Src/zsh.h, Test/A04redirect.ztst: redirections in
 	function definitions are applied at execution not definition.
diff --git a/Src/exec.c b/Src/exec.c
index 1c2a9044c..cedadc86a 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -4306,6 +4306,7 @@ execfuncdef(Estate state, Eprog redir_prog)
     Shfunc shf;
     char *s = NULL;
     int signum, nprg, sbeg, nstrs, npats, len, plen, i, htok = 0, ret = 0;
+    int nfunc = 0;
     Wordcode beg = state->pc, end;
     Eprog prog;
     Patprog *pp;
@@ -4330,6 +4331,8 @@ execfuncdef(Estate state, Eprog redir_prog)
 	}
     }
 
+    DPUTS(!names && redir_prog,
+	  "Passing redirection to anon function definition.");
     while (!names || (s = (char *) ugetnode(names))) {
 	if (!names) {
 	    prog = (Eprog) zhalloc(sizeof(*prog));
@@ -4371,7 +4374,15 @@ execfuncdef(Estate state, Eprog redir_prog)
 	shf->node.flags = 0;
 	shf->filename = ztrdup(scriptfilename);
 	shf->lineno = lineno;
-	shf->redir = redir_prog;
+	/*
+	 * redir_prog is permanently allocated --- but if
+	 * this function has multiple names we need an additional
+	 * one.
+	 */
+	if (nfunc++ && redir_prog)
+	    shf->redir = dupeprog(redir_prog, 0);
+	else
+	    shf->redir = redir_prog;
 	shfunc_set_sticky(shf);
 
 	if (!names) {
@@ -4427,6 +4438,10 @@ execfuncdef(Estate state, Eprog redir_prog)
 	    shfunctab->addnode(shfunctab, ztrdup(s), shf);
 	}
     }
+    if (!nfunc && redir_prog) {
+	/* For completeness, shouldn't happen */
+	freeeprog(redir_prog);
+    }
     state->pc = end;
     return ret;
 }
diff --git a/Test/A04redirect.ztst b/Test/A04redirect.ztst
index 436ae59cd..6c38a3194 100644
--- a/Test/A04redirect.ztst
+++ b/Test/A04redirect.ztst
@@ -491,3 +491,19 @@
 >	print I want to tell you about $var
 >	print Also, this might be an error >&2
 >} < input2 > output2 2>&1
+
+  1func 2func 3func() { print Ich heisse $0 } >output3
+  for i in 1 2 3; do
+    f=${i}func
+    print Running $f
+    $f
+    cat output3
+    unfunction $f
+  done
+0:multiply named functions with redirection
+>Running 1func
+>Ich heisse 1func
+>Running 2func
+>Ich heisse 2func
+>Running 3func
+>Ich heisse 3func