The branch main has been updated by kevans:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=4e380e8474609875c4cf5277b3755ac29079a8b5

commit 4e380e8474609875c4cf5277b3755ac29079a8b5
Author:     Kyle Evans <[email protected]>
AuthorDate: 2021-09-23 05:26:52 +0000
Commit:     Kyle Evans <[email protected]>
CommitDate: 2021-09-29 18:03:34 +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.
    Differential Revision:  https://reviews.freebsd.org/D32072
---
 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
 }
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to