From nobody@FreeBSD.org  Wed Jun 20 18:20:58 2012
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id BC699106564A
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 20 Jun 2012 18:20:58 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 8DBF88FC18
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 20 Jun 2012 18:20:58 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id q5KIKwIW013837
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 20 Jun 2012 18:20:58 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id q5KIKwOZ013836;
	Wed, 20 Jun 2012 18:20:58 GMT
	(envelope-from nobody)
Message-Id: <201206201820.q5KIKwOZ013836@red.freebsd.org>
Date: Wed, 20 Jun 2012 18:20:58 GMT
From: Garrett Cooper <yaneurabeya@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] diff exit code always reports "trouble" when there are differences between 2 files
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         169274
>Category:       bin
>Synopsis:       [patch] diff(1) exit code always reports "trouble" when there are differences between 2 files
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jun 20 18:30:11 UTC 2012
>Closed-Date:    Thu Jun 21 01:54:27 UTC 2012
>Last-Modified:  Sun Feb 03 22:30:39 UTC 2013
>Originator:     Garrett Cooper
>Release:        9-STABLE
>Organization:
EMC Isilon
>Environment:
FreeBSD forza.west.isilon.com 9.0-STABLE FreeBSD 9.0-STABLE #0 r236977M: Tue Jun 12 17:38:29 PDT 2012     root@forza.west.isilon.com:/usr/obj/usr/src/sys/FORZA  amd64
>Description:
diff doesn't do the right thing according to the manpage differentiating errors from differences; from diff(1)...

RETURN VALUE
       diff returns 0 if the files are identical or 1 if the files differ.  If
       one or both of the files cannot be opened, then the return value is set
       to 2.

Example:

$ diff valid.output unittest.dip >/dev/null
$ echo $?
2
$

The patch attached fixes this logic error and another inconsistency with "magic numbers":

$ diff -q /usr/src/contrib/diff/src/diff.c  /usr/src/contrib/diff/src/diff.c ; echo $?
0
$ diff -q /usr/src/contrib/diff/src/diff.c  /usr/src/contrib/diff/src/diff.h ; echo $?
Files /usr/src/contrib/diff/src/diff.c and /usr/src/contrib/diff/src/diff.h differ
1
$ diff -q /usr/src/contrib/diff/src/diff.c  /usr/src/contrib/diff/src/diff.c~ ; echo $?
diff: /usr/src/contrib/diff/src/diff.c~: No such file or directory
2
$ diff -N /usr/src/contrib/diff/src/diff.c /usr/src/contrib/diff/src/diff.c~ >/dev/null; echo $?
1
>How-To-Repeat:
diff /usr/src/contrib/diff/src/diff.c  /usr/src/contrib/diff/src/diff.h >/dev/null
ec=$?
if [ $ec -eq 1 ]
then
    echo PASS
else
    echo FAIL
fi
>Fix:


Patch attached with submission follows:

Index: contrib/diff/src/analyze.c
===================================================================
--- contrib/diff/src/analyze.c	(revision 237106)
+++ contrib/diff/src/analyze.c	(working copy)
@@ -771,7 +771,7 @@
 }
 
 /* If CHANGES, briefly report that two files differed.
-   Return 2 if trouble, CHANGES otherwise.  */
+   Returns CHANGES.  */
 static int
 briefly_report (int changes, struct file_data const filevec[])
 {
@@ -780,8 +780,7 @@
       char const *label0 = file_label[0] ? file_label[0] : filevec[0].name;
       char const *label1 = file_label[1] ? file_label[1] : filevec[1].name;
       message ("Files %s and %s differ\n", label0, label1);
-      if (! brief)
-	changes = 2;
+      changes = 1;
     }
 
   return changes;
Index: contrib/diff/src/diff.c
===================================================================
--- contrib/diff/src/diff.c	(revision 237106)
+++ contrib/diff/src/diff.c	(working copy)
@@ -261,7 +261,7 @@
   char *numend;
 
   /* Do our initializations.  */
-  exit_failure = 2;
+  exit_failure = EXIT_TROUBLE;
   initialize_main (&argc, &argv);
   program_name = argv[0];
   setlocale (LC_ALL, "");


>Release-Note:
>Audit-Trail:

From: Xin LI <delphij@gmail.com>
To: Garrett Cooper <yaneurabeya@gmail.com>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/169274: [patch] diff exit code always reports "trouble" when
 there are differences between 2 files
Date: Wed, 20 Jun 2012 12:13:31 -0700

 > $ diff valid.output unittest.dip >/dev/null
 > $ echo $?
 > 2
 
 I tried a few possible permutations and got expected result (when file
 is not accessible I got 2, and otherwise 1), except the case that one
 file is binary.  It's not clear to me whether this is a bug or a
 feature, as our diff(1) does not have a RETURN VALUE section.  With
 your proposed change, diff no longer distinguishes "trouble outputting
 the diff because at least one file is binary and you don't know it"
 and "I know it's binary (--brief) or I know what I am doing (--text),
 just let me know if there is difference", which sounds like a
 regression IMHO.
 
 > The patch attached fixes this logic error and another inconsistency with =
 "magic numbers":
 
 As a rule, cosmetic changes like change in the second one should never
 be applied on contributed code unless they are really broken.
 
 If for a BSD licensed diff maintained by ourselves this would be a
 desirable change.
 
 > $ diff -q /usr/src/contrib/diff/src/diff.c =C2=A0/usr/src/contrib/diff/sr=
 c/diff.c ; echo $?
 > 0
 
 This is expected.
 
 > $ diff -q /usr/src/contrib/diff/src/diff.c =C2=A0/usr/src/contrib/diff/sr=
 c/diff.h ; echo $?
 > Files /usr/src/contrib/diff/src/diff.c and /usr/src/contrib/diff/src/diff=
 .h differ
 > 1
 
 This is expected.
 
 > $ diff -q /usr/src/contrib/diff/src/diff.c =C2=A0/usr/src/contrib/diff/sr=
 c/diff.c~ ; echo $?
 > diff: /usr/src/contrib/diff/src/diff.c~: No such file or directory
 > 2
 
 This is expected.
 
 > $ diff -N /usr/src/contrib/diff/src/diff.c /usr/src/contrib/diff/src/diff=
 .c~ >/dev/null; echo $?
 > 1
 
 This is expected.  What's wrong here?
 
 >>How-To-Repeat:
 > diff /usr/src/contrib/diff/src/diff.c =C2=A0/usr/src/contrib/diff/src/dif=
 f.h >/dev/null
 > ec=3D$?
 > if [ $ec -eq 1 ]
 > then
 > =C2=A0 =C2=A0echo PASS
 > else
 > =C2=A0 =C2=A0echo FAIL
 > fi
 
 I got "PASS" here...
 
 Cheers,
 --=20
 Xin LI <delphij@delphij.net> https://www.delphij.net/
 FreeBSD - The Power to Serve! Live free or die

From: Garrett Cooper <yaneurabeya@gmail.com>
To: Xin LI <delphij@gmail.com>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/169274: [patch] diff exit code always reports "trouble" when
 there are differences between 2 files
Date: Wed, 20 Jun 2012 12:34:27 -0700

 On Wed, Jun 20, 2012 at 12:13 PM, Xin LI <delphij@gmail.com> wrote:
 >> $ diff valid.output unittest.dip >/dev/null
 >> $ echo $?
 >> 2
 >
 > I tried a few possible permutations and got expected result (when file
 > is not accessible I got 2, and otherwise 1), except the case that one
 > file is binary. =A0It's not clear to me whether this is a bug or a
 > feature, as our diff(1) does not have a RETURN VALUE section.
 
 This is what I was referring to:
 
        FILES  are  `FILE1  FILE2'  or `DIR1 DIR2' or `DIR FILE...' or `FILE=
 ...
        DIR'.  If --from-file or --to-file is given, there are no  restricti=
 ons
        on  FILES.  If a FILE is `-', read standard input.  Exit status is 0=
  if
        inputs are the same, 1 if different, 2 if trouble.
 
 The definition of "trouble" here is unnecessarily ambiguous. I
 interpret trouble to be:
 1. open failure.
 2. stat failure.
 3. read failure.
 etc.
 
 Comparing a binary file and text file does not constitute "trouble" --
 they're just different.
 
 It concerns me because there's a fine line -- in some cases -- between
 binary and text files, depending on the content in the file (I'm
 thinking of .shar files for instance or uuencoded scripts).
 
 > With your proposed change, diff no longer distinguishes "trouble outputti=
 ng
 > the diff because at least one file is binary and you don't know it"
 > and "I know it's binary (--brief) or I know what I am doing (--text),
 > just let me know if there is difference", which sounds like a
 > regression IMHO.
 
 Ok. That was the difference (binary vs text):
 
 $ file valid.output unittest.dip
 valid.output: ASCII text
 unittest.dip: data
 
 Where is that requirement mentioned in the manpage though? I can't
 find it in the GNU diffutils manpage.
 
 If this is a BSD diff requirement, then it's doing something clearly
 different from GNU diff implementation. Whether or not the BSD
 implementation has to conform is another thing entirely, but it would
 be nice to keep the inconsistencies down to a minimum if at all
 possible.
 
 >> The patch attached fixes this logic error and another inconsistency with=
  "magic numbers":
 >
 > As a rule, cosmetic changes like change in the second one should never
 > be applied on contributed code unless they are really broken.
 
 Ok.
 
 > If for a BSD licensed diff maintained by ourselves this would be a
 > desirable change.
 
 ...
 
 > This is expected. =A0What's wrong here?
 
 Nothing was wrong with that case; just trying to prove that my change
 worked as expected (sorry for the accidental ambiguity).
 
 >>>How-To-Repeat:
 >> diff /usr/src/contrib/diff/src/diff.c =A0/usr/src/contrib/diff/src/diff.=
 h >/dev/null
 >> ec=3D$?
 >> if [ $ec -eq 1 ]
 >> then
 >> =A0 =A0echo PASS
 >> else
 >> =A0 =A0echo FAIL
 >> fi
 >
 > I got "PASS" here...
 
 Yeah, I see where I got confused given the info above. Still -- I
 don't see why comparing a binary stream and a text stream should be
 considered "trouble" (esp. when "trouble" isn't well defined) as
 they're both just streams of 0s and 1s and all I care about is whether
 or not they were the same.
 
 Thanks!
 -Garrett

From: Garrett Cooper <yaneurabeya@gmail.com>
To: Xin LI <delphij@gmail.com>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/169274: [patch] diff exit code always reports "trouble" when
 there are differences between 2 files
Date: Wed, 20 Jun 2012 12:44:04 -0700

 On Wed, Jun 20, 2012 at 12:34 PM, Garrett Cooper <yaneurabeya@gmail.com> wrote=
 :
 > On Wed, Jun 20, 2012 at 12:13 PM, Xin LI <delphij@gmail.com> wrote:
 >>> $ diff valid.output unittest.dip >/dev/null
 >>> $ echo $?
 >>> 2
 >>
 >> I tried a few possible permutations and got expected result (when file
 >> is not accessible I got 2, and otherwise 1), except the case that one
 >> file is binary. =A0It's not clear to me whether this is a bug or a
 >> feature, as our diff(1) does not have a RETURN VALUE section.
 >
 > This is what I was referring to:
 >
 > =A0 =A0 =A0 FILES =A0are =A0`FILE1 =A0FILE2' =A0or `DIR1 DIR2' or `DIR FI=
 LE...' or `FILE...
 > =A0 =A0 =A0 DIR'. =A0If --from-file or --to-file is given, there are no =
 =A0restrictions
 > =A0 =A0 =A0 on =A0FILES. =A0If a FILE is `-', read standard input. =A0Exi=
 t status is 0 if
 > =A0 =A0 =A0 inputs are the same, 1 if different, 2 if trouble.
 >
 > The definition of "trouble" here is unnecessarily ambiguous. I
 > interpret trouble to be:
 > 1. open failure.
 > 2. stat failure.
 > 3. read failure.
 > etc.
 >
 > Comparing a binary file and text file does not constitute "trouble" --
 > they're just different.
 >
 > It concerns me because there's a fine line -- in some cases -- between
 > binary and text files, depending on the content in the file (I'm
 > thinking of .shar files for instance or uuencoded scripts).
 >
 >> With your proposed change, diff no longer distinguishes "trouble outputt=
 ing
 >> the diff because at least one file is binary and you don't know it"
 >> and "I know it's binary (--brief) or I know what I am doing (--text),
 >> just let me know if there is difference", which sounds like a
 >> regression IMHO.
 >
 > Ok. That was the difference (binary vs text):
 >
 > $ file valid.output unittest.dip
 > valid.output: ASCII text
 > unittest.dip: data
 >
 > Where is that requirement mentioned in the manpage though? I can't
 > find it in the GNU diffutils manpage.
 >
 > If this is a BSD diff requirement, then it's doing something clearly
 > different from GNU diff implementation. Whether or not the BSD
 > implementation has to conform is another thing entirely, but it would
 > be nice to keep the inconsistencies down to a minimum if at all
 > possible.
 
 Classic Garrett and screwing up context -- there's only one diff in
 base and it's GNU diff.
 
 Thanks,
 -Garrett

From: Garrett Cooper <yaneurabeya@gmail.com>
To: Xin LI <delphij@gmail.com>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/169274: [patch] diff exit code always reports "trouble" when
 there are differences between 2 files
Date: Wed, 20 Jun 2012 12:57:28 -0700

 On Wed, Jun 20, 2012 at 12:44 PM, Garrett Cooper <yaneurabeya@gmail.com> wrote=
 :
 > On Wed, Jun 20, 2012 at 12:34 PM, Garrett Cooper <yaneurabeya@gmail.com> wro=
 te:
 >> On Wed, Jun 20, 2012 at 12:13 PM, Xin LI <delphij@gmail.com> wrote:
 >>>> $ diff valid.output unittest.dip >/dev/null
 >>>> $ echo $?
 >>>> 2
 >>>
 >>> I tried a few possible permutations and got expected result (when file
 >>> is not accessible I got 2, and otherwise 1), except the case that one
 >>> file is binary. =A0It's not clear to me whether this is a bug or a
 >>> feature, as our diff(1) does not have a RETURN VALUE section.
 >>
 >> This is what I was referring to:
 >>
 >> =A0 =A0 =A0 FILES =A0are =A0`FILE1 =A0FILE2' =A0or `DIR1 DIR2' or `DIR F=
 ILE...' or `FILE...
 >> =A0 =A0 =A0 DIR'. =A0If --from-file or --to-file is given, there are no =
 =A0restrictions
 >> =A0 =A0 =A0 on =A0FILES. =A0If a FILE is `-', read standard input. =A0Ex=
 it status is 0 if
 >> =A0 =A0 =A0 inputs are the same, 1 if different, 2 if trouble.
 >>
 >> The definition of "trouble" here is unnecessarily ambiguous. I
 >> interpret trouble to be:
 >> 1. open failure.
 >> 2. stat failure.
 >> 3. read failure.
 >> etc.
 >>
 >> Comparing a binary file and text file does not constitute "trouble" --
 >> they're just different.
 >>
 >> It concerns me because there's a fine line -- in some cases -- between
 >> binary and text files, depending on the content in the file (I'm
 >> thinking of .shar files for instance or uuencoded scripts).
 >>
 >>> With your proposed change, diff no longer distinguishes "trouble output=
 ting
 >>> the diff because at least one file is binary and you don't know it"
 >>> and "I know it's binary (--brief) or I know what I am doing (--text),
 >>> just let me know if there is difference", which sounds like a
 >>> regression IMHO.
 >>
 >> Ok. That was the difference (binary vs text):
 >>
 >> $ file valid.output unittest.dip
 >> valid.output: ASCII text
 >> unittest.dip: data
 >>
 >> Where is that requirement mentioned in the manpage though? I can't
 >> find it in the GNU diffutils manpage.
 >>
 >> If this is a BSD diff requirement, then it's doing something clearly
 >> different from GNU diff implementation. Whether or not the BSD
 >> implementation has to conform is another thing entirely, but it would
 >> be nice to keep the inconsistencies down to a minimum if at all
 >> possible.
 >
 > Classic Garrett and screwing up context -- there's only one diff in
 > base and it's GNU diff.
 
 Oh cool -- I forgot that GNU projects don't have useful manpages. The
 infopage concurs with what you said (
 http://www.gnu.org/software/diffutils/manual/diffutils.html#Binary ):
 
 Normally, differing binary files count as trouble because the
 resulting diff output does not capture all the differences. This
 trouble causes diff to exit with status 2. However, this trouble
 cannot occur with the --text (-a) option, or with the --brief (-q)
 option, as these options both cause diff to generate a form of output
 that represents differences as requested.
 
 Please close this PR (-_-).
 
 Thanks,
 -Garrett
State-Changed-From-To: open->closed 
State-Changed-By: linimon 
State-Changed-When: Thu Jun 21 01:54:19 UTC 2012 
State-Changed-Why:  
Closed at submitter's request. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=169274 
>Unformatted:
