[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: diff: incorrect and undocumented cmp output when stdout is redirecte
From: |
Paul Eggert |
Subject: |
Re: diff: incorrect and undocumented cmp output when stdout is redirected |
Date: |
Thu, 09 Mar 2006 12:48:07 -0800 |
User-agent: |
Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux) |
Good catch. Wow, that bug has been in GNU cmp ever since it was
entered into CVS in 1991.
>> The output of the cmp command should be documented.
The current documentation says this: is it not enough?
What more needs to be said?
By default, @command{cmp} outputs nothing if the two files have the
same contents. If one file is a prefix of the other, @command{cmp}
prints to standard error a message of the following form:
@example
cmp: EOF on @var{shorter-file}
@end example
Otherwise, @command{cmp} prints to standard output a message of the
following form:
@example
@var{from-file} @var{to-file} differ: char @var{byte-number}, line
@var{line-number}
@end example
The message formats can differ outside the @acronym{POSIX} locale.
Also, @acronym{POSIX} allows the @acronym{EOF} message to be followed
by a blank and some additional information.
Anyway, I installed the following patch:
2006-03-09 Paul Eggert <address@hidden>
* src/cmp.c (type_no_stdout): New constant.
(main): Use it to avoid bug when the "EOF on foo" message is
generated and stdout is /dev/null.
Problem reported by Vincent Lefevre (Debian bug 356083).
--- src/cmp.c 5 Jan 2006 07:23:55 -0000 1.39
+++ src/cmp.c 9 Mar 2006 20:33:00 -0000
@@ -78,6 +78,7 @@ static enum comparison_type
{
type_first_diff, /* Print the first difference. */
type_all_diffs, /* Print all differences. */
+ type_no_stdout, /* Do not output to stdout; only stderr. */
type_status /* Exit status only. */
} comparison_type;
@@ -317,7 +318,12 @@ main (int argc, char **argv)
if (fstat (STDOUT_FILENO, &outstat) == 0
&& stat (NULL_DEVICE, &nullstat) == 0
&& 0 < same_file (&outstat, &nullstat))
- comparison_type = type_status;
+ comparison_type =
+ ((fstat (STDERR_FILENO, &outstat) == 0
+ ? 0 < same_file (&outstat, &nullstat)
+ : errno == EBADF)
+ ? type_status
+ : type_no_stdout);
}
/* If only a return code is needed,
@@ -356,7 +362,7 @@ main (int argc, char **argv)
for (f = 0; f < 2; f++)
if (close (file_desc[f]) != 0)
error (EXIT_TROUBLE, errno, "%s", file[f]);
- if (exit_status != 0 && comparison_type != type_status)
+ if (exit_status != EXIT_SUCCESS && comparison_type < type_no_stdout)
check_stdout ();
exit (exit_status);
return exit_status;
@@ -536,6 +542,9 @@ cmp (void)
while (first_diff < smaller);
ret = EXIT_FAILURE;
break;
+
+ case type_no_stdout:
+ break;
}
}