On Fri, Jan 08, 2021 at 07:09:01PM -0800, Jordan Geoghegan wrote: > Hey folks, > > I've noticed some surprising behaviour from cmp(1) when using the '-s' flag. > > It appears that cmp -s is ignoring the byte offset arguments I'm giving it. > > I don't want to waste time babbling, so here's an example snippet to show > what I'm talking about: > > #!/bin/sh > > echo 'my line' > /tmp/1.txt > echo 'my other line' >> /tmp/1.txt > echo 'same same' >> /tmp/1.txt > > echo 'my differnt line' > /tmp/2.txt > echo 'my other different line' >> /tmp/2.txt > echo 'same same' >> /tmp/2.txt > > # Determine byte offsets (we only want to compare lines >= 3) > offset1="$(head -2 /tmp/1.txt | wc -c)" > offset2="$(head -2 /tmp/2.txt | wc -c)" > > # Compare files and show exit code > cmp /tmp/1.txt /tmp/2.txt "$offset1" "$offset2" > printf '\nReturn code = %s\n' "$?" > > cmp -s /tmp/1.txt /tmp/2.txt "$offset1" "$offset2" > printf '\nReturn code with "-s" = %s\n' "$?" > > As you can see, 'cmp -s' returns an exit code of '1', unlike cmp without the > '-s' which returns '0'. > > Not sure what to make of this, I noticed this same behaviour on DragonflyBSD > and FreeBSD, so maybe I'm just missing something obvious. This certainly > caused some frustration before I figured out what was going on. > > Regards, > > Jordan >
This is a bug. It has been there since the beginning, according to http://cvsweb.openbsd.org/src/usr.bin/cmp/regular.c FreeBSD has it fixed, NetBSD not. -Otto Index: regular.c =================================================================== RCS file: /cvs/src/usr.bin/cmp/regular.c,v retrieving revision 1.12 diff -u -p -r1.12 regular.c --- regular.c 6 Feb 2015 23:21:59 -0000 1.12 +++ regular.c 9 Jan 2021 06:53:20 -0000 @@ -51,15 +51,15 @@ c_regular(int fd1, char *file1, off_t sk off_t byte, length, line; int dfound; - if (sflag && len1 != len2) - exit(1); - if (skip1 > len1) eofmsg(file1); len1 -= skip1; if (skip2 > len2) eofmsg(file2); len2 -= skip2; + + if (sflag && len1 != len2) + exit(1); length = MINIMUM(len1, len2); if (length > SIZE_MAX) {

