summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/options.yo10
-rw-r--r--Src/exec.c24
-rw-r--r--Src/options.c1
-rw-r--r--Src/zsh.h1
5 files changed, 34 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index a0353c8c8..c00131e32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2002-12-04  Peter Stephenson  <pws@csr.com>
+
+	* 17979: Doc/Zsh/options.yo, Src/exec.c, Src/options.c, Src/zsh.h:
+	Add ERR_RETURN option, similiar to ERR_EXIT option.
+
 2002-11-26  Peter Stephenson  <pws@csr.com>
 
 	* 17967: Test/B02typeset.ztst: globbable arguments to
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index 27f6b7e91..3616ae50c 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -380,6 +380,16 @@ If a command has a non-zero exit status, execute the tt(ZERR)
 trap, if set, and exit.  This is disabled while running initialization
 scripts.
 )
+pindex(ERR_RETURN)
+cindex(function return, on error)
+cidnex(return from function, on error)
+item(tt(ERR_RETURN))(
+If a command has a non-zero exit status, return immediately from the
+enclosing function.  The logic is identical to that for tt(ERR_EXIT),
+except that an implicit tt(return) statement is executed instead of an
+tt(exit).  This will trigger an exit at the outermost level of a
+non-interactive script.
+)
 pindex(EXEC)
 cindex(command execution, enabling)
 item(tt(EXEC) (tt(PLUS()n), ksh: tt(PLUS()n)) <D>)(
diff --git a/Src/exec.c b/Src/exec.c
index ca7b2061f..76ca437f4 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -924,13 +924,23 @@ sublist_done:
 		dotrap(SIGZERR);
 		donetrap = 1;
 	    }
-	    if (lastval && isset(ERREXIT)) {
-		if (sigtrapped[SIGEXIT])
-		    dotrap(SIGEXIT);
-		if (mypid != getpid())
-		    _exit(lastval);
-		else
-		    exit(lastval);
+	    if (lastval) {
+		int errreturn = isset(ERRRETURN) && 
+		    (isset(INTERACTIVE) || locallevel || sourcelevel);
+		int errexit = isset(ERREXIT) || 
+		    (isset(ERRRETURN) && !errreturn);
+		if (errexit) {
+		    if (sigtrapped[SIGEXIT])
+			dotrap(SIGEXIT);
+		    if (mypid != getpid())
+			_exit(lastval);
+		    else
+			exit(lastval);
+		}
+		if (errreturn) {
+		    retflag = 1;
+		    breaks = loops;
+		}
 	    }
 	}
 	if (ltype & Z_END)
diff --git a/Src/options.c b/Src/options.c
index 841a3cb82..da1e9efac 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -109,6 +109,7 @@ static struct optname optns[] = {
 {NULL, "cshnullglob",	      OPT_EMULATE|OPT_CSH,	 CSHNULLGLOB},
 {NULL, "equals",	      OPT_EMULATE|OPT_ZSH,	 EQUALS},
 {NULL, "errexit",	      OPT_EMULATE,		 ERREXIT},
+{NULL, "errreturn",	      OPT_EMULATE,		 ERRRETURN},
 {NULL, "exec",		      OPT_ALL,			 EXECOPT},
 {NULL, "extendedglob",	      OPT_EMULATE,		 EXTENDEDGLOB},
 {NULL, "extendedhistory",     OPT_CSH,			 EXTENDEDHISTORY},
diff --git a/Src/zsh.h b/Src/zsh.h
index 62136719a..9d402b242 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1419,6 +1419,7 @@ enum {
     CSHNULLGLOB,
     EQUALS,
     ERREXIT,
+    ERRRETURN,
     EXECOPT,
     EXTENDEDGLOB,
     EXTENDEDHISTORY,