about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Src/builtin.c5
-rw-r--r--Src/exec.c2
3 files changed, 11 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 24108151d..870422a9b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,12 @@
 	* 22464: Src/Zle/zle_main.c: an error in prompt substitution could
 	cause bad recursion karma.
 
+2006-03-02  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 22317: Src/builtins.c, Src/exec.c: exiting the shell from
+	code forked from within a function doesn't maintain the
+	exit status.
+
 2006-01-10  Peter Stephenson  <pws@csr.com>
 
 	* 22151: Src/text.c: a here-string got too many quotes when
diff --git a/Src/builtin.c b/Src/builtin.c
index 0d729aab0..1af193f8f 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -4092,12 +4092,15 @@ bin_break(char *name, char **argv, UNUSED(Options ops), int func)
 	}
 	/*FALLTHROUGH*/
     case BIN_EXIT:
-	if (locallevel) {
+	if (locallevel > forklevel) {
 	    /*
 	     * We don't exit directly from functions to allow tidying
 	     * up, in particular EXIT traps.  We still need to perform
 	     * the usual interactive tests to see if we can exit at
 	     * all, however.
+	     *
+	     * If we are forked, we exit the shell at the function depth
+	     * at which we became a subshell, hence the comparison.
 	     */
 	    if (stopmsg || (zexit(0,2), !stopmsg)) {
 		retflag = 1;
diff --git a/Src/exec.c b/Src/exec.c
index 2db264435..b8583923f 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -3657,7 +3657,7 @@ doshfunc(char *name, Eprog prog, LinkList doshargs, int flags, int noreturnval)
     popheap();
 
     if (exit_pending) {
-	if (locallevel) {
+	if (locallevel > forklevel) {
 	    /* Still functions to return: force them to do so. */
 	    retflag = 1;
 	    breaks = loops;