Date: Sun, 3 Oct 2021 05:20:57 GMT From: Kyle Evans <kevans@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: a67180b4b770 - stable/12 - cmp: add -n, --bytes to limit number of bytes to compare Message-ID: <202110030520.1935Kvww020953@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=a67180b4b7706d504351c96359459876e9e0fb4b commit a67180b4b7706d504351c96359459876e9e0fb4b Author: Kyle Evans <kevans@FreeBSD.org> AuthorDate: 2021-09-23 05:26:52 +0000 Commit: Kyle Evans <kevans@FreeBSD.org> CommitDate: 2021-10-03 05:19:56 +0000 cmp: add -n, --bytes to limit number of bytes to compare This is compatible with GNU cmp. Reviewed by: markj Sponsored by: Klara, Inc. (cherry picked from commit 4e380e8474609875c4cf5277b3755ac29079a8b5) --- usr.bin/cmp/cmp.1 | 6 ++++++ usr.bin/cmp/cmp.c | 18 +++++++++++++----- usr.bin/cmp/extern.h | 7 ++++--- usr.bin/cmp/link.c | 6 ++++-- usr.bin/cmp/regular.c | 8 +++++--- usr.bin/cmp/special.c | 4 ++-- usr.bin/cmp/tests/cmp_test2.sh | 23 +++++++++++++++++++++++ 7 files changed, 57 insertions(+), 15 deletions(-) diff --git a/usr.bin/cmp/cmp.1 b/usr.bin/cmp/cmp.1 index 6980f73e7be5..511e09ac8628 100644 --- a/usr.bin/cmp/cmp.1 +++ b/usr.bin/cmp/cmp.1 @@ -41,6 +41,7 @@ .Nm .Op Fl l | s | x .Op Fl hz +.Op Fl -bytes Ns Cm = Ns Ar num .Ar file1 file2 .Op Ar skip1 Op Ar skip2 .Sh DESCRIPTION @@ -62,6 +63,10 @@ Do not follow symbolic links. .It Fl l , Fl -verbose Print the byte number (decimal) and the differing byte values (octal) for each difference. +.It Fl n Ar num , Fl -bytes= Ns num +Only compare up to +.Ar num +bytes. .It Fl s , Fl -silent , Fl -quiet Print nothing for differing files; return exit status only. @@ -165,6 +170,7 @@ utility is expected to be compatible. The .Fl h , +.Fl n , .Fl x , and .Fl z diff --git a/usr.bin/cmp/cmp.c b/usr.bin/cmp/cmp.c index bab69125e83e..384c273f4632 100644 --- a/usr.bin/cmp/cmp.c +++ b/usr.bin/cmp/cmp.c @@ -67,6 +67,7 @@ bool lflag, sflag, xflag, zflag; static const struct option long_opts[] = { {"verbose", no_argument, NULL, 'l'}, + {"bytes", required_argument, NULL, 'n'}, {"silent", no_argument, NULL, 's'}, {"quiet", no_argument, NULL, 's'}, {NULL, no_argument, NULL, 0} @@ -78,14 +79,14 @@ int main(int argc, char *argv[]) { struct stat sb1, sb2; - off_t skip1, skip2; + off_t skip1, skip2, limit; int ch, fd1, fd2, oflag; bool special; const char *file1, *file2; skip1 = skip2 = 0; oflag = O_RDONLY; - while ((ch = getopt_long(argc, argv, "+hlsxz", long_opts, NULL)) != -1) + while ((ch = getopt_long(argc, argv, "+hln:sxz", long_opts, NULL)) != -1) switch (ch) { case 'h': /* Don't follow symlinks */ oflag |= O_NOFOLLOW; @@ -93,6 +94,13 @@ main(int argc, char *argv[]) case 'l': /* print all differences */ lflag = true; break; + case 'n': /* Limit */ + if (expand_number(optarg, &limit) < 0 || limit < 0) { + fprintf(stderr, "Invalid --bytes: %s\n", + optarg); + usage(); + } + break; case 's': /* silent run */ sflag = true; break; @@ -163,7 +171,7 @@ main(int argc, char *argv[]) if (fd1 == -1) { if (fd2 == -1) { - c_link(file1, skip1, file2, skip2); + c_link(file1, skip1, file2, skip2, limit); exit(0); } else if (!sflag) errx(ERR_EXIT, "%s: Not a symbolic link", file2); @@ -201,7 +209,7 @@ main(int argc, char *argv[]) } if (special) - c_special(fd1, file1, skip1, fd2, file2, skip2); + c_special(fd1, file1, skip1, fd2, file2, skip2, limit); else { if (zflag && sb1.st_size != sb2.st_size) { if (!sflag) @@ -210,7 +218,7 @@ main(int argc, char *argv[]) exit(DIFF_EXIT); } c_regular(fd1, file1, skip1, sb1.st_size, - fd2, file2, skip2, sb2.st_size); + fd2, file2, skip2, sb2.st_size, limit); } exit(0); } diff --git a/usr.bin/cmp/extern.h b/usr.bin/cmp/extern.h index 82c5ea42b175..803319a50ca4 100644 --- a/usr.bin/cmp/extern.h +++ b/usr.bin/cmp/extern.h @@ -38,9 +38,10 @@ #define DIFF_EXIT 1 #define ERR_EXIT 2 /* error exit code */ -void c_link(const char *, off_t, const char *, off_t); -void c_regular(int, const char *, off_t, off_t, int, const char *, off_t, off_t); -void c_special(int, const char *, off_t, int, const char *, off_t); +void c_link(const char *, off_t, const char *, off_t, off_t); +void c_regular(int, const char *, off_t, off_t, int, const char *, off_t, + off_t, off_t); +void c_special(int, const char *, off_t, int, const char *, off_t, off_t); void diffmsg(const char *, const char *, off_t, off_t); void eofmsg(const char *); diff --git a/usr.bin/cmp/link.c b/usr.bin/cmp/link.c index 9193147e830e..f0b4482a5792 100644 --- a/usr.bin/cmp/link.c +++ b/usr.bin/cmp/link.c @@ -40,7 +40,8 @@ __FBSDID("$FreeBSD$"); #include "extern.h" void -c_link(const char *file1, off_t skip1, const char *file2, off_t skip2) +c_link(const char *file1, off_t skip1, const char *file2, off_t skip2, + off_t limit) { char buf1[PATH_MAX], *p1; char buf2[PATH_MAX], *p2; @@ -72,7 +73,8 @@ c_link(const char *file1, off_t skip1, const char *file2, off_t skip2) dfound = 0; byte = 1; - for (p1 = buf1 + skip1, p2 = buf2 + skip2; *p1 && *p2; p1++, p2++) { + for (p1 = buf1 + skip1, p2 = buf2 + skip2; + *p1 && *p2 && (limit == 0 || byte <= limit); p1++, p2++) { if ((ch = *p1) != *p2) { if (xflag) { dfound = 1; diff --git a/usr.bin/cmp/regular.c b/usr.bin/cmp/regular.c index fe639663a560..a60398620282 100644 --- a/usr.bin/cmp/regular.c +++ b/usr.bin/cmp/regular.c @@ -60,7 +60,7 @@ static void segv_handler(int); void c_regular(int fd1, const char *file1, off_t skip1, off_t len1, - int fd2, const char *file2, off_t skip2, off_t len2) + int fd2, const char *file2, off_t skip2, off_t len2, off_t limit) { struct sigaction act, oact; cap_rights_t rights; @@ -86,15 +86,17 @@ c_regular(int fd1, const char *file1, off_t skip1, off_t len1, off2 = ROUNDPAGE(skip2); length = MIN(len1, len2); + if (limit > 0) + length = MIN(length, limit); if ((m1 = remmap(NULL, fd1, off1)) == NULL) { - c_special(fd1, file1, skip1, fd2, file2, skip2); + c_special(fd1, file1, skip1, fd2, file2, skip2, limit); return; } if ((m2 = remmap(NULL, fd2, off2)) == NULL) { munmap(m1, MMAP_CHUNK); - c_special(fd1, file1, skip1, fd2, file2, skip2); + c_special(fd1, file1, skip1, fd2, file2, skip2, limit); return; } diff --git a/usr.bin/cmp/special.c b/usr.bin/cmp/special.c index 930fcd5492ff..25f755f6e70a 100644 --- a/usr.bin/cmp/special.c +++ b/usr.bin/cmp/special.c @@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$"); void c_special(int fd1, const char *file1, off_t skip1, - int fd2, const char *file2, off_t skip2) + int fd2, const char *file2, off_t skip2, off_t limit) { int ch1, ch2; off_t byte, line; @@ -76,7 +76,7 @@ c_special(int fd1, const char *file1, off_t skip1, if (getc(fp2) == EOF) goto eof; - for (byte = line = 1;; ++byte) { + for (byte = line = 1; limit == 0 || byte <= limit; ++byte) { ch1 = getc(fp1); ch2 = getc(fp2); if (ch1 == EOF || ch2 == EOF) diff --git a/usr.bin/cmp/tests/cmp_test2.sh b/usr.bin/cmp/tests/cmp_test2.sh index 334e9f357730..c513984daf8b 100755 --- a/usr.bin/cmp/tests/cmp_test2.sh +++ b/usr.bin/cmp/tests/cmp_test2.sh @@ -91,10 +91,33 @@ skipsuff_body() atf_check -s exit:0 cmp -s a b 1k 1k } +atf_test_case limit +limit_head() +{ + atf_set "descr" "Test cmp(1) -n (limit)" +} +limit_body() +{ + echo -n "aaaabbbb" > a + echo -n "aaaaxxxx" > b + + atf_check -s exit:1 -o ignore cmp -s a b + atf_check -s exit:0 cmp -sn 4 a b + atf_check -s exit:0 cmp -sn 3 a b + atf_check -s exit:1 -o ignore cmp -sn 5 a b + + # Test special, too. The implementation for link is effectively + # identical. + atf_check -s exit:0 -e empty -x "cat a | cmp -sn 4 b -" + atf_check -s exit:0 -e empty -x "cat a | cmp -sn 3 b -" + atf_check -s exit:1 -o ignore -x "cat a | cmp -sn 5 b -" +} + atf_init_test_cases() { atf_add_test_case special atf_add_test_case symlink atf_add_test_case pr252542 atf_add_test_case skipsuff + atf_add_test_case limit }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202110030520.1935Kvww020953>