diffutils/diffutils-3.10-cmp-s-empty.patch
2024-07-30 10:39:36 +02:00

73 lines
2.9 KiB
Diff

commit ff1096a0c24c3a302a58864392270e6622e21a03
Author: Paul Eggert <eggert@cs.ucla.edu>
Date: Wed Jun 21 11:19:13 2023 -0700
cmp: fix -s bug when comparing /proc files
* NEWS: Mention this.
* src/cmp.c (main, cmp): Do not trust st_size == 0, as it may
be a /proc file.
* tests/brief-vs-stat-zero-kernel-lies: Also test cmp -s.
diff --git a/NEWS b/NEWS
index 0b7cf48..00ee5b6 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,12 @@ GNU diffutils NEWS -*- outline -*-
cmp/diff can again work with file dates past Y2K38
[bug introduced in 3.9]
+ cmp -s no longer mishandles /proc files, for which the Linux kernel
+ reports a zero size even when nonempty. For example, the following
+ shell command now outputs nothing, as it should:
+ cp /proc/cmdline t; cmp -s /proc/cmdline t || echo files differ
+ [bug present since "the beginning"]
+
diff -D no longer fails to output #ifndef lines.
[bug#61193 introduced in 3.9]
diff --git a/src/cmp.c b/src/cmp.c
index 4bf0a4c..936125c 100644
--- a/src/cmp.c
+++ b/src/cmp.c
@@ -338,13 +338,14 @@ main (int argc, char **argv)
}
/* If only a return code is needed,
- and if both input descriptors are associated with plain files,
+ and both input descriptors are associated with plain files,
+ and the file sizes are nonzero so they are not Linux /proc files,
conclude that the files differ if they have different sizes
and if more bytes will be compared than are in the smaller file. */
if (comparison_type == type_status
- && 0 <= stat_buf[0].st_size && S_ISREG (stat_buf[0].st_mode)
- && 0 <= stat_buf[1].st_size && S_ISREG (stat_buf[1].st_mode))
+ && 0 < stat_buf[0].st_size && S_ISREG (stat_buf[0].st_mode)
+ && 0 < stat_buf[1].st_size && S_ISREG (stat_buf[1].st_mode))
{
off_t s0 = stat_buf[0].st_size - file_position (0);
off_t s1 = stat_buf[1].st_size - file_position (1);
@@ -401,7 +402,7 @@ cmp (void)
? bytes : TYPE_MAXIMUM (off_t));
for (f = 0; f < 2; f++)
- if (0 <= stat_buf[f].st_size && S_ISREG (stat_buf[f].st_mode))
+ if (0 < stat_buf[f].st_size && S_ISREG (stat_buf[f].st_mode))
{
off_t file_bytes = stat_buf[f].st_size - file_position (f);
if (file_bytes < byte_number_max)
diff --git a/tests/brief-vs-stat-zero-kernel-lies b/tests/brief-vs-stat-zero-kernel-lies
index 82b33e6..7cc2dc7 100755
--- a/tests/brief-vs-stat-zero-kernel-lies
+++ b/tests/brief-vs-stat-zero-kernel-lies
@@ -35,4 +35,9 @@ printf 'diff\0--brief\0/proc/self/cmdline\0bin\0' > bin || framework_failure_
diff --brief /proc/self/cmdline bin > out 2>&1 || fail=1
compare /dev/null out || fail=1
+# Similarly for cmp -s.
+printf 'cmp\0-s\0/proc/self/cmdline\0bin\0' > bin || framework_failure_
+cmp -s /proc/self/cmdline bin > out 2>&1 || fail=1
+compare /dev/null out || fail=1
+
Exit $fail