From fenner@thud.FreeBSD.org  Tue Mar  4 18:25:27 1997
Received: from thud.FreeBSD.org (thud.FreeBSD.ORG [204.216.27.19])
          by freefall.freebsd.org (8.8.5/8.8.5) with ESMTP id SAA11268
          for <FreeBSD-gnats-submit@freebsd.org>; Tue, 4 Mar 1997 18:25:26 -0800 (PST)
Received: (from fenner@localhost) by thud.FreeBSD.org (8.8.5/8.6.12) id SAA15291; Tue, 4 Mar 1997 18:25:12 -0800 (PST)
Message-Id: <199703050225.SAA15291@thud.FreeBSD.org>
Date: Tue, 4 Mar 1997 18:25:12 -0800 (PST)
From: fenner@parc.xerox.com
Reply-To: fenner@parc.xerox.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: sh: ! fails to negate the return value of a pipeline
X-Send-Pr-Version: 3.2

>Number:         2879
>Category:       bin
>Synopsis:       sh: ! fails to negate the return value of a pipeline
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    steve
>State:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Mar  4 18:30:02 PST 1997
>Closed-Date:    Sun Apr 27 20:39:57 PDT 1997
>Last-Modified:  Sun Apr 27 20:40:39 PDT 1997
>Originator:     Bill Fenner
>Release:        FreeBSD 3.0-970209-SNAP i386
>Organization:
Xerox
>Environment:

	
/bin/sh from -current (2.2 is not (yet?) affected)

>Description:

	
! fails to negate the return value of a pipeline.  The sh man page says:

       If the reserved word ! does not precede the pipeline, the
       exit status is the exit status of the last command speci-
       fied in the pipeline.  Otherwise, the exit status is the
       logical NOT of the exit status of the last command.

However, I see the following behavior:

$ if ! date | false; then echo hi; fi
$ if ! date | true; then echo hi; fi
hi

! works when not associated with a pipeline:

$ if ! false; then echo hi; fi
hi
$ if ! true; then echo hi; fi

All of the above work properly in 2.2 .

>How-To-Repeat:

	
Use ! to negate the return value of a pipeline.  Watch it fail to negate
the return value of the pipeline.


>Fix:
	
	
I'm pretty suspicious of rev 1.17 of parser.c, since it appears to
change where in the parse tree the NNOT (23) appears.  

In 2.2, the parse tree for the command line "! date | false" looks
something like

evaltree(0x539cc: 23) called	[!]
evaltree(0x53988: 2) called	[|]
evaltree(0x53978: 1) called	[date]
evaltree(0x539bc: 1) called	[false]

In 3.0, the parse tree for the same command line looks like

evaltree(0x19b54: 2) called	[|]
evaltree(0x19b4c: 23) called	[!]
evaltree(0x19b3c: 1) called	[date]
evaltree(0x19b88: 1) called	[false]

e.g. it looks like the return value of date is being negated and
then discarded.  Presumably there was a reason to make the changes
in 1.17, and since I don't understand that reason I can't suggest
a fix (other than back them out).
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->steve 
Responsible-Changed-By: fenner 
Responsible-Changed-When: Sun Mar 9 23:41:43 PST 1997 
Responsible-Changed-Why:  
Steve made the commit that caused the behavior to change 

From: Bill Fenner <fenner@parc.xerox.com>
To: freebsd-gnats-submit@freebsd.org, fenner@parc.xerox.com
Cc:  Subject: Re: bin/2879: sh: ! fails to negate the return value of a pipeline
Date: Sun, 9 Mar 1997 23:40:53 PST

 I did find a workaround:
 
 if ! ( date | false ); then echo hi; fi
 
 works, as one might expect.
 
   Bill
State-Changed-From-To: open->closed 
State-Changed-By: steve 
State-Changed-When: Sun Apr 27 20:39:57 PDT 1997 
State-Changed-Why:  
Fixed in rev 1.20 of parser.c. 
>Unformatted:
