From 4d43343eb495b0de6b810ce19790ebee24d365c9 Mon Sep 17 00:00:00 2001 From: Michael Mikonos <127171689+mknos@users.noreply.github.com> Date: Mon, 21 Oct 2024 19:39:57 +0800 Subject: [PATCH] cmp: helpful EOF messages * It's trivial to provide extra descriptive output when files differ at EOF, as done by GNU cmp * Shell scripts running cmp would normally use the -s flag and check the exit code, i.e. the text description shouldn't be depended upon for portability %dd if=/dev/urandom bs=512 count=1 of=rnd %cp rnd rnd2 %echo >> rnd2 %touch empty %perl cmp rnd rnd2 # test1: non-empty files, eof on arg1 cmp: EOF on rnd after byte 512, in line 6 %perl cmp rnd2 rnd # test2: non-empty files, eof on arg2 cmp: EOF on rnd after byte 512, in line 6 %perl cmp empty rnd # test3: arg1 empty cmp: EOF on empty which is empty %perl cmp rnd empty # test4: arg2 empty cmp: EOF on empty which is empty --- bin/cmp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/bin/cmp b/bin/cmp index 6d5db019..494bc3bb 100755 --- a/bin/cmp +++ b/bin/cmp @@ -48,9 +48,9 @@ use constant EX_USAGE => 2; use constant ST_INO => 1; use constant ST_SIZE => 7; -my $Program = basename($0); +use constant READSZ => 10_000; -my $chunk_size = 10_000; # how many bytes in a gulp +my $Program = basename($0); my $volume=1; # controlled by -s and -l @@ -123,8 +123,8 @@ if (!$fh1 && !$fh2) { # with the behavior when skip >= # filesize. if ($volume) { - warn "$Program: EOF on $file1\n" unless $stat1[ST_SIZE]; - warn "$Program: EOF on $file2\n" unless $stat2[ST_SIZE]; + warn "$Program: EOF on $file1 which is empty\n" unless $stat1[ST_SIZE]; + warn "$Program: EOF on $file2 which is empty\n" unless $stat2[ST_SIZE]; } exit EX_DIFFERENT; } @@ -167,8 +167,8 @@ if ($skip2) { } } -READ: while (defined ($read_in1 = sysread $fh1, $buffer1, $chunk_size)) { - $read_in2 = sysread $fh2, $buffer2, $chunk_size; +READ: while (defined ($read_in1 = sysread $fh1, $buffer1, READSZ)) { + $read_in2 = sysread $fh2, $buffer2, READSZ; $read_in2 = 0 unless defined $read_in2; # sysread failed my $checklength = min($read_in1, $read_in2); @@ -199,12 +199,14 @@ READ: while (defined ($read_in1 = sysread $fh1, $buffer1, $chunk_size)) { $lines_read += $buffer1 =~ tr[\n][\n]; } $bytes_read += $checklength; + my $nlines = $lines_read + 1; + my $nbytes = $bytes_read + 1; if ($read_in1 < $read_in2) { - warn "$Program: EOF on $file1\n" unless $saw_difference or !$volume; + warn "$Program: EOF on $file1 after byte $nbytes, in line $nlines\n" unless $saw_difference or !$volume; exit EX_DIFFERENT; } elsif ($read_in1 > $read_in2) { - warn "$Program: EOF on $file2\n" unless $saw_difference or !$volume; + warn "$Program: EOF on $file2 after byte $nbytes, in line $nlines\n" unless $saw_difference or !$volume; exit EX_DIFFERENT; } elsif ($read_in1 == 0) { exit EX_DIFFERENT;