diff --git a/ChangeLog b/ChangeLog
index 318c8df33..1d1d8f9f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2016-10-05 Peter Stephenson
+ * 39571: Src/exec.c, Test/C03traps.ztst: "&&" inside a shell
+ function could mess up ERR_EXIT outside.
+
* 39568: Src/exec.c, Test/C03traps.ztst: "! "
should suppress ERR_EXIT inside the complex command.
diff --git a/Src/exec.c b/Src/exec.c
index 741c80e30..c0ed2c475 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -1229,7 +1229,7 @@ execlist(Estate state, int dont_change_job, int exiting)
}
while (wc_code(code) == WC_LIST && !breaks && !retflag && !errflag) {
int donedebug;
- int this_noerrexit = 0;
+ int this_noerrexit = 0, this_donetrap = 0;
ltype = WC_LIST_TYPE(code);
csp = cmdsp;
@@ -1353,10 +1353,10 @@ execlist(Estate state, int dont_change_job, int exiting)
/* We've skipped to the end of the list, not executing *
* the final pipeline, so don't perform error handling *
* for this sublist. */
- donetrap = 1;
+ this_donetrap = 1;
goto sublist_done;
} else if (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END) {
- donetrap = 1;
+ this_donetrap = 1;
/*
* Treat this in the same way as if we reached
* the end of the sublist normally.
@@ -1386,10 +1386,10 @@ execlist(Estate state, int dont_change_job, int exiting)
/* We've skipped to the end of the list, not executing *
* the final pipeline, so don't perform error handling *
* for this sublist. */
- donetrap = 1;
+ this_donetrap = 1;
goto sublist_done;
} else if (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END) {
- donetrap = 1;
+ this_donetrap = 1;
/*
* Treat this in the same way as if we reached
* the end of the sublist normally.
@@ -1439,7 +1439,7 @@ sublist_done:
/* Check whether we are suppressing traps/errexit *
* (typically in init scripts) and if we haven't *
* already performed them for this sublist. */
- if (!noerrexit && !this_noerrexit && !donetrap) {
+ if (!noerrexit && !this_noerrexit && !donetrap && !this_donetrap) {
if (sigtrapped[SIGZERR] && lastval) {
dotrap(SIGZERR);
donetrap = 1;
diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst
index 0faec02e9..5057dcf6e 100644
--- a/Test/C03traps.ztst
+++ b/Test/C03traps.ztst
@@ -476,7 +476,7 @@
fi
}
fn
-0:ERRRETURN not triggered in if condition
+0:ERR_RETURN not triggered in if condition
>Oh, yes
fn() {
@@ -490,7 +490,7 @@
fi
}
fn
-1:ERRRETURN in "if"
+1:ERR_RETURN in "if"
fn() {
emulate -L zsh
@@ -503,7 +503,7 @@
fi
}
fn
-1:ERRRETURN in "else" branch (regression test)
+1:ERR_RETURN in "else" branch (regression test)
$ZTST_testdir/../Src/zsh -f =(<<<"
if false; then
@@ -515,7 +515,7 @@
print Yes
fi
")
-0:ERRRETURN when false "if" is the first statement in an "else" (regression)
+0:ERR_RETURN when false "if" is the first statement in an "else" (regression)
>Yes
F:Must be tested with a top-level script rather than source or function
@@ -527,7 +527,7 @@ F:Must be tested with a top-level script rather than source or function
print after
}
fn
-1:ERRRETURN, basic case
+1:ERR_RETURN, basic case
>before
fn() {
@@ -539,7 +539,7 @@ F:Must be tested with a top-level script rather than source or function
print after
}
fn
-0:ERRETURN with "!"
+0:ERR_RETURN with "!"
>before
>after
@@ -553,7 +553,7 @@ F:Must be tested with a top-level script rather than source or function
print after
}
fn
-1:ERRETURN with "!" and a following false
+1:ERR_RETURN with "!" and a following false
>before
fn() {
@@ -566,7 +566,7 @@ F:Must be tested with a top-level script rather than source or function
print after
}
fn
-0:ERRETURN with "!" suppressed inside complex structure
+0:ERR_RETURN with "!" suppressed inside complex structure
>before
>after
@@ -580,9 +580,22 @@ F:Must be tested with a top-level script rather than source or function
print after
}
fn
-1:ERRETURN with no "!" suppression (control case)
+1:ERR_RETURN with no "!" suppression (control case)
>before
+ (setopt err_return
+ fn() {
+ print before-in
+ false && false
+ }
+ print before-out
+ fn
+ print after-out
+ )
+1:ERR_RETURN with "&&" in function (regression test)
+>before-out
+>before-in
+
%clean
rm -f TRAPEXIT