Subject: Re: bin/17870: /bin/sh bug on expanding $? in here-documents
To: None <netbsd-bugs@netbsd.org>
From: David Laight <david@l8s.co.uk>
List: netbsd-bugs
Date: 08/08/2002 10:06:13
Test case is:
! :
cat <<EOF
$?
EOF
Which is expeced to output '1' (not '0').
I had a look at this. I think:
- the status of every command is written to 'exitstatus'
- $? substitutes in 'oexitstatus'
- some commands don't necessarily write to 'exitstatus' so there
is an assignment 'exitstatus = 0' to ensure 'success' is set.
- $? may be substitued for after 'exitstatus = 0' has been set.
- expandarg() is normally preceeded by 'oexitstatus = exitstatus'
to ensure that the correct status is substituted.
Now 'evalcommand' sets 'oexitstatus = exitstatus' before its
loop through (what looks like) the arguments calling expandarg()
for each one. However it also sets 'exitstatus = 0' for this
command. This means that expredir() copies the 0 into oexitstatus
before calling expandarg().
Now deferring the 'extstatus = 0' in evalcommand until after the
call to expredir seems to work - until you try:
! :
cat >`echo /dev/tty` <<EOF
$?
EOF
Also using:
cat >`echo /dev/tty; ! :` <<EOF
$?
EOF
outputs the failure from the embedded command.
cat `echo -; ! :` <<EOF
is fine...
I think the correct solution is to move the 'oexitstatus = exitstatus'
from inside the loop in expredir() to before each call to it.
(Except the one in evalcommand - where it is already set.)
Anyone care to comment?
David
--
David Laight: david@l8s.co.uk