Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: exiting status from forked shell started within function



A rather subtle bug turned up when I was playing with Dan's test in
22277.

% child() { exit 33; }
% child &
[1] 12804
[1]  + 12804 exit 33    child
% fn2() { child & }
% fn2
[2] 12809
[2]  + 12809 done       child

The exit status from the child is wrong when it is started in the
background within a function.  This is because we currently only exit
functions from the outermost context.  However, if the context where the
process was started is not the outermost one we need to exit there.

I'll commit this fix with a test based on 222277, the fix itself in
22281, plus some calls to waitforpid() that I missed in another
function.  The fix here (and probably only that) should be ported
to 4.2.

Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.151
diff -u -r1.151 builtin.c
--- Src/builtin.c	7 Nov 2005 09:37:34 -0000	1.151
+++ Src/builtin.c	2 Mar 2006 21:52:59 -0000
@@ -4119,12 +4119,15 @@
 	}
 	/*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;
Index: Src/exec.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/exec.c,v
retrieving revision 1.95
diff -u -r1.95 exec.c
--- Src/exec.c	25 Nov 2005 10:36:20 -0000	1.95
+++ Src/exec.c	2 Mar 2006 21:53:02 -0000
@@ -3852,7 +3852,7 @@
     popheap();
 
     if (exit_pending) {
-	if (locallevel) {
+	if (locallevel > forklevel) {
 	    /* Still functions to return: force them to do so. */
 	    retflag = 1;
 	    breaks = loops;

-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page still at http://www.pwstephenson.fsnet.co.uk/



Messages sorted by: Reverse Date, Date, Thread, Author