From: Peter Stephenson <pws@csr.com>
To: zsh-workers@sunsite.dk
Subject: Re: bug: $? after empty command
Date: Thu, 9 Jul 2009 15:41:24 +0100 [thread overview]
Message-ID: <20090709154124.2cd2a227@news01> (raw)
In-Reply-To: <loom.20090709T130223-845@post.gmane.org>
On Thu, 9 Jul 2009 13:12:20 +0000 (UTC)
Eric Blake <ebb9@byu.net> wrote:
> POSIX requires that the execution of an empty command change $? to 0, as shown
> here with bash:
>
> $ zsh -c 'foo=; false; $foo; echo $?'
> 1
I'm not aware that that's deliberate shell behaviour, and indeed I
wouldn't have expected it. It *is* deliberate behaviour that the status is
not reset simply by hitting return at the interactive prompt, but that's
actually a different issue, not affected by the following.
The fix for this is quite subtle because of the case
zsh -c 'false; $(exit 3); echo $?'
which should print 3, but I think I've finally found a way that handles
both.
Index: Src/exec.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/exec.c,v
retrieving revision 1.165
diff -u -r1.165 exec.c
--- Src/exec.c 15 Mar 2009 01:04:50 -0000 1.165
+++ Src/exec.c 9 Jul 2009 14:38:41 -0000
@@ -151,6 +151,15 @@
/**/
int cmdoutval;
+/*
+ * This is set by an exiting $(...) substitution to indicate we need
+ * to retain the status. We initialize it to zero if we think we need
+ * to reset the status for a command.
+ */
+
+/**/
+int use_cmdoutval;
+
/* The context in which a shell function is called, see SFC_* in zsh.h. */
/**/
@@ -2262,6 +2271,14 @@
*/
if (!args && varspc)
lastval = errflag ? errflag : cmdoutval;
+ /*
+ * If there are arguments, we should reset the status for the
+ * command before execution---unless we are using the result of a
+ * command substitution, which will be indicated by setting
+ * use_cmdoutval to 1. We haven't kicked those off yet, so
+ * there's no race.
+ */
+ use_cmdoutval = !args;
for (i = 0; i < 10; i++) {
save[i] = -2;
@@ -2478,7 +2495,12 @@
lastval = 0;
return;
} else {
- cmdoutval = lastval;
+ /*
+ * No arguments. Reset the status if there were
+ * arguments before and no command substitution
+ * has provided a status.
+ */
+ cmdoutval = use_cmdoutval ? lastval : 0;
if (varspc)
addvars(state, varspc, 0);
if (errflag)
@@ -4674,6 +4696,7 @@
es->badcshglob = badcshglob;
es->cmdoutpid = cmdoutpid;
es->cmdoutval = cmdoutval;
+ es->use_cmdoutval = use_cmdoutval;
es->trap_return = trap_return;
es->trap_state = trap_state;
es->trapisfunc = trapisfunc;
@@ -4704,6 +4727,7 @@
badcshglob = exstack->badcshglob;
cmdoutpid = exstack->cmdoutpid;
cmdoutval = exstack->cmdoutval;
+ use_cmdoutval = exstack->use_cmdoutval;
trap_return = exstack->trap_return;
trap_state = exstack->trap_state;
trapisfunc = exstack->trapisfunc;
Index: Src/signals.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/signals.c,v
retrieving revision 1.54
diff -u -r1.54 signals.c
--- Src/signals.c 11 Feb 2009 20:42:16 -0000 1.54
+++ Src/signals.c 9 Jul 2009 14:38:41 -0000
@@ -494,6 +494,7 @@
*procsubval = (0200 | WTERMSIG(status));
else
*procsubval = WEXITSTATUS(status);
+ use_cmdoutval = 1;
get_usage();
cont = 1;
break;
Index: Src/zsh.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v
retrieving revision 1.158
diff -u -r1.158 zsh.h
--- Src/zsh.h 2 Jul 2009 13:48:36 -0000 1.158
+++ Src/zsh.h 9 Jul 2009 14:38:41 -0000
@@ -930,6 +930,7 @@
int badcshglob;
pid_t cmdoutpid;
int cmdoutval;
+ int use_cmdoutval;
int trap_return;
int trap_state;
int trapisfunc;
Index: Test/A01grammar.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/A01grammar.ztst,v
retrieving revision 1.22
diff -u -r1.22 A01grammar.ztst
--- Test/A01grammar.ztst 6 Jul 2009 20:44:29 -0000 1.22
+++ Test/A01grammar.ztst 9 Jul 2009 14:38:41 -0000
@@ -23,6 +23,10 @@
true | false
1:Exit status of pipeline with builtins (false)
+ false
+ $nonexistent_variable
+0:Executing command that evaluates to empty resets status
+
fn() { local foo; read foo; print $foo; }
coproc fn
print -p coproc test output
--
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
next prev parent reply other threads:[~2009-07-09 14:41 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-09 13:12 Eric Blake
2009-07-09 14:41 ` Peter Stephenson [this message]
2009-07-09 21:17 ` Eric Blake
2009-07-09 21:41 ` Eric Blake
2009-07-10 9:02 ` Peter Stephenson
2009-07-10 22:05 ` Peter Stephenson
2009-07-11 16:39 ` Peter Stephenson
2009-07-11 18:43 ` Bart Schaefer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090709154124.2cd2a227@news01 \
--to=pws@csr.com \
--cc=zsh-workers@sunsite.dk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).