Skip to content

Commit

Permalink
cmp: helpful EOF messages
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
mknos authored Oct 21, 2024
1 parent 437e404 commit 4d43343
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions bin/cmp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 4d43343

Please sign in to comment.