2006-05-09 Paul Eggert * src/cmp.c (cmp): The previous fix wasn't quite right either, as it mishandled 'cmp A B >/dev/null' when A is shorter than B and differs before A's end-of-file, by outputting a bogus EOF message. Also, it was inefficient if A and B were large. 2006-05-07 Jim Meyering (tiny change) Fix bug introduced in 2006-03-09 change: cmp always exits successfully, when stdout is redirected to /dev/null. * src/cmp.c (cmp): When there's a difference, arrange to return nonzero also when comparison_type is the new (from 2006-03-09) type_no_stdout. 2006-03-09 Paul Eggert * 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). Index: cmp.c =================================================================== RCS file: /sources/diffutils/diffutils/src/cmp.c,v retrieving revision 1.39 retrieving revision 1.40 diff -u -a -p -u -p -a -r1.39 -r1.40 --- cmp.c 5 Jan 2006 07:23:55 -0000 1.39 +++ cmp.c 9 Mar 2006 20:38:11 -0000 1.40 @@ -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; } } Index: cmp.c =================================================================== RCS file: /sources/diffutils/diffutils/src/cmp.c,v retrieving revision 1.40 retrieving revision 1.41 diff -u -a -p -u -p -a -r1.40 -r1.41 --- cmp.c 9 Mar 2006 20:38:11 -0000 1.40 +++ cmp.c 9 Mar 2006 20:54:39 -0000 1.41 @@ -318,12 +318,7 @@ main (int argc, char **argv) if (fstat (STDOUT_FILENO, &outstat) == 0 && stat (NULL_DEVICE, &nullstat) == 0 && 0 < same_file (&outstat, &nullstat)) - comparison_type = - ((fstat (STDERR_FILENO, &outstat) == 0 - ? 0 < same_file (&outstat, &nullstat) - : errno == EBADF) - ? type_status - : type_no_stdout); + comparison_type = type_no_stdout; } /* If only a return code is needed, Index: cmp.c =================================================================== RCS file: /sources/diffutils/diffutils/src/cmp.c,v retrieving revision 1.43 retrieving revision 1.44 diff -u -a -p -u -p -a -r1.43 -r1.44 --- cmp.c 13 Mar 2006 19:11:17 -0000 1.43 +++ cmp.c 8 May 2006 01:41:04 -0000 1.44 @@ -536,10 +536,10 @@ cmp (void) first_diff++; } while (first_diff < smaller); - ret = EXIT_FAILURE; - break; + /* Fall through. */ case type_no_stdout: + ret = EXIT_FAILURE; break; } } Index: cmp.c =================================================================== RCS file: /sources/diffutils/diffutils/src/cmp.c,v retrieving revision 1.44 retrieving revision 1.45 diff -u -a -p -u -p -a -r1.44 -r1.45 --- cmp.c 8 May 2006 01:41:04 -0000 1.44 +++ cmp.c 9 May 2006 22:57:20 -0000 1.45 @@ -382,7 +382,7 @@ cmp (void) word *buffer1 = buffer[1]; char *buf0 = (char *) buffer0; char *buf1 = (char *) buffer1; - int ret = EXIT_SUCCESS; + int differing = 0; int f; int offset_width IF_LINT (= 0); @@ -536,17 +536,18 @@ cmp (void) first_diff++; } while (first_diff < smaller); + differing = -1; + break; - /* Fall through. */ case type_no_stdout: - ret = EXIT_FAILURE; + differing = 1; break; } } if (read0 != read1) { - if (comparison_type != type_status) + if (differing <= 0 && comparison_type != type_status) { /* See POSIX 1003.1-2001 for this format. */ fprintf (stderr, _("cmp: EOF on %s\n"), file[read1 < read0]); @@ -555,9 +556,9 @@ cmp (void) return EXIT_FAILURE; } } - while (read0 == buf_size); + while (differing <= 0 && read0 == buf_size); - return ret; + return differing == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } /* Compare two blocks of memory P0 and P1 until they differ,