zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: exit status
@ 2006-11-10  9:40 Peter Stephenson
  2006-11-10 15:58 ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 2006-11-10  9:40 UTC (permalink / raw)
  To: Zsh hackers list

A thread on the Austin group suggests the exit status of the shell
should be available in exit traps.  This is potentially useful,
particularly since there's no other way of getting the exit status.
It's hard to see how it can cause problems since previously the exit
status wasn't tied to any particular command (it was whatever happened
to run just before the exit) so didn't have a useful value inside the
trap.

There was one special case: on an implicit exit it always was and still
is the status of the last command before exit, however as you couldn't
tell if it was an implicit exit from the trap even that wasn't
particularly useful.

This will apply inside the next zshexit hooks, too.  It already applies
to traps on return from functions---that's a separate piece of code.
(It's preserved if multiple functions/hooks run; this is already handled
by the context used for a trap or hook.)

Obviously the status is only available until the first statement within
the trap/hook has run.

Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.87
diff -u -r1.87 builtins.yo
--- Doc/Zsh/builtins.yo	20 Sep 2006 09:22:34 -0000	1.87
+++ Doc/Zsh/builtins.yo	10 Nov 2006 09:37:12 -0000
@@ -1252,6 +1252,8 @@
 If var(sig) is tt(0) or tt(EXIT)
 and the tt(trap) statement is executed inside the body of a function,
 then the command var(arg) is executed after the function completes.
+The value of tt($?) at the start of execution is the exit status of the
+shell or the return status of the function exiting.
 If var(sig) is tt(0) or tt(EXIT)
 and the tt(trap) statement is not executed inside the body of a function,
 then the command var(arg) is executed when the shell terminates.
Index: Doc/Zsh/func.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/func.yo,v
retrieving revision 1.14
diff -u -r1.14 func.yo
--- Doc/Zsh/func.yo	9 Nov 2006 11:04:11 -0000	1.14
+++ Doc/Zsh/func.yo	10 Nov 2006 09:37:12 -0000
@@ -248,6 +248,8 @@
 item(tt(TRAPEXIT))(
 Executed when the shell exits,
 or when the current function exits if defined inside a function.
+The value of tt($?) at the start of execution is the exit status of the
+shell or the return status of the function exiting.
 )
 findex(TRAPZERR)
 findex(TRAPERR)
Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.168
diff -u -r1.168 builtin.c
--- Src/builtin.c	9 Nov 2006 11:04:11 -0000	1.168
+++ Src/builtin.c	10 Nov 2006 09:37:14 -0000
@@ -4434,6 +4434,7 @@
 #endif
 	}
     }
+    lastval = val;
     if (sigtrapped[SIGEXIT])
 	dotrap(SIGEXIT);
     callhookfunc("zshexit", NULL, 1);


-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: PATCH: exit status
  2006-11-10  9:40 PATCH: exit status Peter Stephenson
@ 2006-11-10 15:58 ` Bart Schaefer
  2006-11-10 16:09   ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2006-11-10 15:58 UTC (permalink / raw)
  To: Zsh hackers list

On Nov 10,  9:40am, Peter Stephenson wrote:
}
} A thread on the Austin group suggests the exit status of the shell
} should be available in exit traps.

I'm leaning towards Don Cragun's camp (the prior-to-this-patch zsh
behavior) on this one.  I think the answer (and a general issue about
the new hook functions, incidentally) is tied to the answer to this
other question:

What is the final exit status of the shell when the exit trap itself
calls exit?

If
	trap 'exit 42' EXIT; exit 1

returns 42 to the calling environment, then Korn and the GNU guys are
correct.  If it exits 1, then Don Cragun is correct.

Similarly, what happens if the zshexit hook calls exit?  What happens
if the zshexit hook calls "return 37"?


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: PATCH: exit status
  2006-11-10 15:58 ` Bart Schaefer
@ 2006-11-10 16:09   ` Peter Stephenson
  2006-11-11  5:28     ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 2006-11-10 16:09 UTC (permalink / raw)
  To: Zsh hackers list

Bart Schaefer wrote:
> On Nov 10,  9:40am, Peter Stephenson wrote:
> }
> } A thread on the Austin group suggests the exit status of the shell
> } should be available in exit traps.
> 
> I'm leaning towards Don Cragun's camp (the prior-to-this-patch zsh
> behavior) on this one.

I can see arguments for both sides; it turns whether you consider the
"exit" command itself to have been executed before the exit traps run,
which is a bit Zen-like.  What finally convinced me is that knowing the
exit status in $? is potentially useful; knowing the status of whatever
command happened to run before is very unlikely to be.  In other
words, if we *do* leave it the old way it simply means the status isn't
useful.

> I think the answer (and a general issue about
> the new hook functions, incidentally) is tied to the answer to this
> other question:
> 
> What is the final exit status of the shell when the exit trap itself
> calls exit?
> 
> If
> 	trap 'exit 42' EXIT; exit 1
> 
> returns 42 to the calling environment, then Korn and the GNU guys are
> correct.  If it exits 1, then Don Cragun is correct.
> 
> Similarly, what happens if the zshexit hook calls exit?  What happens
> if the zshexit hook calls "return 37"?

I alluded to this briefly: hooks and traps run in special contexts which
don't alter the global status.  This has been the case for some time
(though I don't think it was originally like that---early versions were
fairly wayward about return statuses).  That's required in some specific
cases --- the DEBUG trap would be unusable (or at least need extreme
care in writing) if its status were returned to the main shell.  Also,
if we have multiple exit hooks and want them to get the same status
(since they shouldn't care about previous hooks) we need their return
statuses to be protected.  That's how it currently works.

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: PATCH: exit status
  2006-11-10 16:09   ` Peter Stephenson
@ 2006-11-11  5:28     ` Bart Schaefer
  2006-11-11 13:13       ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2006-11-11  5:28 UTC (permalink / raw)
  To: Zsh hackers list

Aside:  Here's an actual bug:

   zsh -fc 'trap "echo \$?" EXIT; echo ${example?oops}'

The EXIT trap is not called when the shell exits on the error caused
by the ${var?message} construct.  (Bash prints "127" in this case;
also, the exit status of zsh on that construct is 1 rather than 127,
but I don't know why bash chose 127.)

On Nov 10,  4:09pm, Peter Stephenson wrote:
}
} I can see arguments for both sides; it turns whether you consider the
} "exit" command itself to have been executed before the exit traps run,
} which is a bit Zen-like.

Think of it as a C program.  If

    int question_mark = 0;
    atexit() { printf("%d\n", question_mark); }
    main() { question_mark = exit(3); }

is a valid program and, when run, prints "3", then I'm on your side.
Otherwise I'm with Cragun.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: PATCH: exit status
  2006-11-11  5:28     ` Bart Schaefer
@ 2006-11-11 13:13       ` Peter Stephenson
  0 siblings, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2006-11-11 13:13 UTC (permalink / raw)
  To: Zsh hackers list

On Fri, 10 Nov 2006 21:28:44 -0800
Bart Schaefer <schaefer@brasslantern.com> wrote:
> Aside:  Here's an actual bug:
> 
>    zsh -fc 'trap "echo \$?" EXIT; echo ${example?oops}'
> 
> The EXIT trap is not called when the shell exits on the error caused
> by the ${var?message} construct.

There are two bugs: we go straight to exit() instead of zexit(), and the
EXIT trap doesn't get run if there has just been an error.  Presumably
it needs to be run unconditionally.  (In fact, now I think about it, I'm
a little bit suspicious that testing for "errflag" before running a
trap, which is right down in the trap handling code, is ever the right
thing to do.)

There's another bug lurking:  the exit might be within a forked
subshell, so I've made it use _exit() in that case.

> (Bash prints "127" in this case;
> also, the exit status of zsh on that construct is 1 rather than 127,
> but I don't know why bash chose 127.)

The only mention I can see in the standard is for a command not found,
which doesn't apply, but I presume status 127 is being used generally to
signal an error in shell processing rather than a command return status.

> On Nov 10,  4:09pm, Peter Stephenson wrote:
> }
> } I can see arguments for both sides; it turns whether you consider the
> } "exit" command itself to have been executed before the exit traps run,
> } which is a bit Zen-like.
> 
> Think of it as a C program.  If
> 
>     int question_mark = 0;
>     atexit() { printf("%d\n", question_mark); }
>     main() { question_mark = exit(3); }
> 
> is a valid program and, when run, prints "3", then I'm on your side.
> Otherwise I'm with Cragun.

You certainly wouldn't expect exit() to return to main() after running,
regardless of the point at which atexit() takes place, so I don't think
this is parallel.  All of which goes to show that there's no killer
argument (that I've heard).

Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.169
diff -u -r1.169 builtin.c
--- Src/builtin.c	10 Nov 2006 09:59:27 -0000	1.169
+++ Src/builtin.c	11 Nov 2006 13:05:12 -0000
@@ -4413,6 +4413,11 @@
      * indicate we shouldn't do any recursive processing.
      */
     in_exit = -1;
+    /*
+     * We want to do all remaining processing regardless of preceeding
+     * errors.
+     */
+    errflag = 0;
 
     if (isset(MONITOR)) {
 	/* send SIGHUP to any jobs left running  */
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.67
diff -u -r1.67 subst.c
--- Src/subst.c	7 Nov 2006 22:47:07 -0000	1.67
+++ Src/subst.c	11 Nov 2006 13:05:16 -0000
@@ -2591,8 +2591,17 @@
 	    if (vunset) {
 		*idend = '\0';
 		zerr("%s: %s", idbeg, *s ? s : "parameter not set");
-		if (!interact)
-		    exit(1);
+		if (!interact) {
+		    if (mypid == getpid()) {
+			/*
+			 * paranoia: don't check for jobs, but there shouldn't
+			 * be any if not interactive.
+			 */
+			stopmsg = 1;
+			zexit(1, 0);
+		    } else
+			_exit(1);
+		}
 		return NULL;
 	    }
 	    break;

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2006-11-11 13:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-11-10  9:40 PATCH: exit status Peter Stephenson
2006-11-10 15:58 ` Bart Schaefer
2006-11-10 16:09   ` Peter Stephenson
2006-11-11  5:28     ` Bart Schaefer
2006-11-11 13:13       ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).