about summary refs log tree commit diff
path: root/Src/exec.c
diff options
context:
space:
mode:
authorPeter Stephenson <p.w.stephenson@ntlworld.com>2016-10-02 19:16:03 +0100
committerPeter Stephenson <p.w.stephenson@ntlworld.com>2016-10-02 19:17:19 +0100
commit6b2585147b842c69faecb136c17dbdda79b3e4b4 (patch)
treed6fff6653a7773bf525482542f6ab4b420221083 /Src/exec.c
parent4f2a1810f2fa1d74008e03a09d66eaff3e5edc9e (diff)
downloadzsh-6b2585147b842c69faecb136c17dbdda79b3e4b4.tar.gz
zsh-6b2585147b842c69faecb136c17dbdda79b3e4b4.tar.xz
zsh-6b2585147b842c69faecb136c17dbdda79b3e4b4.zip
39540: "! command" should suppress ERR_EXIT and ERR_RETURN
Diffstat (limited to 'Src/exec.c')
-rw-r--r--Src/exec.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/Src/exec.c b/Src/exec.c
index 2714edbcb..906cf6cca 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -1226,6 +1226,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;
 
 	ltype = WC_LIST_TYPE(code);
 	csp = cmdsp;
@@ -1309,9 +1310,12 @@ execlist(Estate state, int dont_change_job, int exiting)
 	    goto sublist_done;
 	}
 	while (wc_code(code) == WC_SUBLIST) {
+	    int isend = (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END);
 	    next = state->pc + WC_SUBLIST_SKIP(code);
 	    if (!oldnoerrexit)
-		noerrexit = (WC_SUBLIST_TYPE(code) != WC_SUBLIST_END);
+		noerrexit = !isend;
+	    if ((WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT) && isend)
+		this_noerrexit = 1;
 	    switch (WC_SUBLIST_TYPE(code)) {
 	    case WC_SUBLIST_END:
 		/* End of sublist; just execute, ignoring status. */
@@ -1427,7 +1431,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 && !donetrap) {
+	if (!noerrexit && !this_noerrexit && !donetrap) {
 	    if (sigtrapped[SIGZERR] && lastval) {
 		dotrap(SIGZERR);
 		donetrap = 1;