about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>2000-02-20 01:27:10 +0000
committerTanaka Akira <akr@users.sourceforge.net>2000-02-20 01:27:10 +0000
commit693e45e9bb52776c7c0e740deeb9a02bb6252884 (patch)
treea88e5a27d15d1da2356b05c61e548697f399ffa0
parentac6487085024cb65b94d761add66835aac6b6a6e (diff)
downloadzsh-693e45e9bb52776c7c0e740deeb9a02bb6252884.tar.gz
zsh-693e45e9bb52776c7c0e740deeb9a02bb6252884.tar.xz
zsh-693e45e9bb52776c7c0e740deeb9a02bb6252884.zip
zsh-workers/9794
-rw-r--r--Src/exec.c12
-rw-r--r--Test/.distfiles2
-rw-r--r--Test/51xtrace.ztst60
3 files changed, 69 insertions, 5 deletions
diff --git a/Src/exec.c b/Src/exec.c
index 81d9dbd1a..a5e347d89 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -129,7 +129,7 @@ struct execstack *exstack;
 /**/
 mod_export Funcstack funcstack;
 
-#define execerr() if (!forked) { lastval = 1; return; } else _exit(1)
+#define execerr() if (!forked) { lastval = 1; goto done; } else _exit(1)
 
 static LinkList args;
 static int doneps4;
@@ -473,6 +473,7 @@ execute(Cmdnam not_used_yet, int dash)
     }
 
     argv = makecline(args);
+    closem(3);
     child_unblock();
     if ((int) strlen(arg0) >= PATH_MAX) {
 	zerr("command too long: %s", arg0, 0);
@@ -1937,9 +1938,12 @@ execcmd(Estate state, int input, int output, int how, int last1)
 
     /* Make a copy of stderr for xtrace output before redirecting */
     fflush(xtrerr);
-    if (xtrerr == stderr &&
-	!(xtrerr = fdopen(movefd(dup(fileno(stderr))), "w")))
-	xtrerr = stderr;
+    if (xtrerr == stderr && (type < WC_SUBSH || type == WC_TIMED)) {
+	if (!(xtrerr = fdopen(movefd(dup(fileno(stderr))), "w")))
+	    xtrerr = stderr;
+	else
+	    fdtable[fileno(xtrerr)] = 3;
+    }
 
     /* Add pipeline input/output to mnodes */
     if (input)
diff --git a/Test/.distfiles b/Test/.distfiles
index daf76cebb..bea0dd621 100644
--- a/Test/.distfiles
+++ b/Test/.distfiles
@@ -3,5 +3,5 @@ DISTFILES_SRC='
     ztst.zsh
     01grammar.ztst 02alias.ztst 03quoting.ztst 04redirect.ztst
     05command.ztst 06arith.ztst 07cond.ztst 08traps.ztst 09funcdef.ztst
-    10prompt.ztst 50cd.ztst
+    10prompt.ztst 50cd.ztst 51xtrace.ztst
 '
diff --git a/Test/51xtrace.ztst b/Test/51xtrace.ztst
new file mode 100644
index 000000000..5dac18ff6
--- /dev/null
+++ b/Test/51xtrace.ztst
@@ -0,0 +1,60 @@
+# Test that xtrace output is correctly generated
+
+%prep
+  mkdir xtrace.tmp && cd xtrace.tmp
+
+%test
+
+  set -x
+  print 'Tracing: builtin'
+  print 'Tracing: builtin 2>file' 2>xtrace.err
+  cat <<<'Tracing: external'
+  cat <<<'Tracing: external 2>file' 2>>xtrace.err
+  ( print 'Tracing: ( builtin )' )
+  ( print 'Tracing: ( builtin ) 2>file' ) 2>>xtrace.err
+  ( cat <<<'Tracing: ( external )' )
+  ( cat <<<'Tracing: ( external ) 2>file' ) 2>>xtrace.err
+  { print 'Tracing: { builtin }' }
+  { print 'Tracing: { builtin } 2>file' } 2>>xtrace.err
+  { cat <<<'Tracing: { external }' }
+  { cat <<<'Tracing: { external } 2>file' } 2>>xtrace.err
+  repeat 1 do print 'Tracing: do builtin done'; done
+  repeat 1 do print 'Tracing: do builtin done 2>file'; done 2>>xtrace.err
+  repeat 1 do cat <<<'Tracing: do external done'; done
+  repeat 1 do cat <<<'Tracing: do external done'; done 2>>xtrace.err
+  set +x
+  cat xtrace.err
+0:xtrace with and without redirection
+>Tracing: builtin
+>Tracing: builtin 2>file
+>Tracing: external
+>Tracing: external 2>file
+>Tracing: ( builtin )
+>Tracing: ( builtin ) 2>file
+>Tracing: ( external )
+>Tracing: ( external ) 2>file
+>Tracing: { builtin }
+>Tracing: { builtin } 2>file
+>Tracing: { external }
+>Tracing: { external } 2>file
+>Tracing: do builtin done
+>Tracing: do builtin done 2>file
+>Tracing: do external done
+>Tracing: do external done
+>+ZTST_execchunk:2> print Tracing: ( builtin ) 2>file
+>+ZTST_execchunk:2> cat
+>+ZTST_execchunk:2> print Tracing: { builtin } 2>file
+>+ZTST_execchunk:2> cat
+>+ZTST_execchunk:2> print Tracing: do builtin done 2>file
+>+ZTST_execchunk:2> cat
+?+ZTST_execchunk:2> print Tracing: builtin
+?+ZTST_execchunk:2> print Tracing: builtin 2>file
+?+ZTST_execchunk:2> cat
+?+ZTST_execchunk:2> cat
+?+ZTST_execchunk:2> print Tracing: ( builtin )
+?+ZTST_execchunk:2> cat
+?+ZTST_execchunk:2> print Tracing: { builtin }
+?+ZTST_execchunk:2> cat
+?+ZTST_execchunk:2> print Tracing: do builtin done
+?+ZTST_execchunk:2> cat
+?+ZTST_execchunk:2> set +x