Date: Wed, 7 Aug 2002 16:22:52 +0200 (CEST) From: "Ralf S.Engelschall" <rse@engelschall.com> To: FreeBSD-gnats-submit@FreeBSD.org Cc: dev@de.cw.net Subject: bin/41410: /bin/sh bug on expanding $? in here-documents Message-ID: <20020807142252.6F12B28693@en1.engelschall.com>
next in thread | raw e-mail | index | archive | help
>Number: 41410
>Category: bin
>Synopsis: /bin/sh bug on expanding $? in here-documents
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Aug 07 07:30:02 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Ralf S. Engelschall
>Release: FreeBSD 4.6-STABLE i386
>Organization:
Cavle & Wireless Germany
>Environment:
System: FreeBSD en1.engelschall.com 4.6-STABLE FreeBSD 4.6-STABLE #0: Fri Jul 26 19:25:01 CEST 2002 root@en1.engelschall.com:/v/dsk/0/g/src/sys/compile/EN1 i386
>Description:
While debugging a build problem of GNU Tar 1.3.25 on FreeBSD 4.6-STABLE
for OpenPKG, I discovered a bug in /bin/sh which is triggered by a
construct in Tar's generated GNU Autoconf script "configure". The bug is
that in here-documents the shell-variable $? is expanded incorrectly.
The appended sample script buggy.sh demonstrates the problem. I ran
"uname -a; /bin/sh buggy.sh | grep attempt" on some of our development
machines and it resulted in the following output:
FreeBSD dv1 4.6-STABLE FreeBSD 4.6-STABLE #0: Sun Jul 14 20:58:49 CEST 2002
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=0 $1=foo $2=bar $baz=quux
attempt 3: $?=0 $1=foo $2=bar $baz=quux
FreeBSD dv2 5.0-CURRENT FreeBSD 5.0-CURRENT #0: Sun Jul 28 10:54:41 CEST 2002
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=0 $1=foo $2=bar $baz=quux
attempt 3: $?=0 $1=foo $2=bar $baz=quux
NetBSD dv3 1.6_BETA3 NetBSD 1.6_BETA3 (DV3) #0: Thu Jun 27 19:09:59 UTC 2002
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=0 $1=foo $2=bar $baz=quux
attempt 3: $?=0 $1=foo $2=bar $baz=quux
Linux dv4 2.4.9-21 #1 Thu Jan 17 14:16:30 EST 2002 i686 unknown
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=1 $1=foo $2=bar $baz=quux
attempt 3: $?=1 $1=foo $2=bar $baz=quux
Linux dv5 2.2.20 #1 Sat Nov 3 18:25:00 CET 2001 i686 unknown
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=1 $1=foo $2=bar $baz=quux
attempt 3: $?=1 $1=foo $2=bar $baz=quux
Linux dv6 2.4.19 #1 SMP Sat Aug 3 15:48:01 CEST 2002 i686 unknown
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=1 $1=foo $2=bar $baz=quux
attempt 3: $?=1 $1=foo $2=bar $baz=quux
SunOS dv8 5.8 Generic_108528-15 sun4u sparc SUNW,Ultra-250
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=1 $1=foo $2=bar $baz=quux
attempt 3: $?=1 $1=foo $2=bar $baz=quux
SunOS dv9 5.9 Generic sun4u sparc SUNW,Ultra-250
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=1 $1=foo $2=bar $baz=quux
attempt 3: $?=1 $1=foo $2=bar $baz=quux
OpenUNIX dv11 5 8.0.0 i386 x86at Caldera UNIX_SVR5
attempt 1: $?=1 $1=foo $2=bar $baz=quux
attempt 2: $?=1 $1=foo $2=bar $baz=quux
attempt 3: $?=1 $1=foo $2=bar $baz=quux
As one can see, the bug is not really FreeBSD specific, because it also
occurs on NetBSD. But all other Unix flavors I tested consistently show
the expected result (three times the value 1). The same happens with GNU
Bash on all platforms (every time the correct value 1). So I have to
assume that the output of /bin/sh on FreeBSD and NetBSD is incorrect and
caused by a bug.
=====================================================================
#!/bin/sh -x
# buggy.sh
set -- foo bar
baz=quux
# attempt #1 (simple echo for comparison)
test yes != yes
echo "attempt 1: \$?=$? \$1=$1 \$2=$2 \$baz=$baz"
# attempt #2 (small here-document)
test yes != yes
cat <<EOF
attempt 2: \$?=$? \$1=$1 \$2=$2 \$baz=$baz
EOF
# attempt #3 (large here-document >= 4KB)
test yes != yes
cat <<EOF
attempt 3: \$?=$? \$1=$1 \$2=$2 \$baz=$baz
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
EOF
=====================================================================
>How-To-Repeat:
$ /bin/sh
$ (exit 42)
$ echo "$?"
42
$ (exit 42)
$ cat <<EOF
> $?
> EOF
0
$ _
>Fix:
I already poked around in the source of /bin/sh in HEAD and RELENG_4, but
was not able to really discover or even solve the bug. I only discovered
that the source of the failure in "attempt 2" seems to be caused by
an assignment of the exit value in eval.c:
Index: eval.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/eval.c,v
retrieving revision 1.27.2.4
diff -u -d -r1.27.2.4 eval.c
--- eval.c 19 Jul 2002 04:38:51 -0000 1.27.2.4
+++ eval.c 7 Aug 2002 14:09:07 -0000
@@ -442,7 +442,9 @@
for (redir = n ; redir ; redir = redir->nfile.next) {
struct arglist fn;
fn.lastp = &fn.list;
+#if 0
oexitstatus = exitstatus;
+#endif
switch (redir->type) {
case NFROM:
case NTO:
With this test-removal I get at least "attempt 2: $?=1 $1=foo $2=bar
$baz=quux". But perhaps now something else is broken, of course. So we
really need someone with more knowledge of the /bin/sh internals to dive
into the source and fix it for us.
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020807142252.6F12B28693>
