aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/cmp/cmp.119
-rw-r--r--usr.bin/cmp/cmp.c30
-rwxr-xr-xusr.bin/cmp/tests/cmp_test2.sh5
3 files changed, 53 insertions, 1 deletions
diff --git a/usr.bin/cmp/cmp.1 b/usr.bin/cmp/cmp.1
index 511e09ac8628..5a56802bd22e 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 -ignore-initial Ns Cm = Ns Ar num1 Ns Op :num2
.Op Fl -bytes Ns Cm = Ns Ar num
.Ar file1 file2
.Op Ar skip1 Op Ar skip2
@@ -60,6 +61,23 @@ The following options are available:
.Bl -tag -width indent
.It Fl h
Do not follow symbolic links.
+.It Fl i Ar num1 Ns Oo :num2 Oc , Fl -ignore-initial= Ns Ar num1 Ns Op :num2
+Skip
+.Ar num1
+bytes from
+.Ar file1 ,
+and optionally skip
+.Ar num2
+bytes from
+.Ar file2 .
+If
+.Ar num2
+is not specified, then
+.Ar num1
+is applied for both
+.Ar file1
+and
+.Ar file2 .
.It Fl l , Fl -verbose
Print the byte number (decimal) and the differing
byte values (octal) for each difference.
@@ -170,6 +188,7 @@ utility is expected to be
compatible.
The
.Fl h ,
+.Fl i ,
.Fl n ,
.Fl x ,
and
diff --git a/usr.bin/cmp/cmp.c b/usr.bin/cmp/cmp.c
index 384c273f4632..256cef8a0c31 100644
--- a/usr.bin/cmp/cmp.c
+++ b/usr.bin/cmp/cmp.c
@@ -66,6 +66,7 @@ bool lflag, sflag, xflag, zflag;
static const struct option long_opts[] =
{
+ {"ignore-initial", required_argument, NULL, 'i'},
{"verbose", no_argument, NULL, 'l'},
{"bytes", required_argument, NULL, 'n'},
{"silent", no_argument, NULL, 's'},
@@ -75,6 +76,25 @@ static const struct option long_opts[] =
static void usage(void);
+static bool
+parse_iskipspec(char *spec, off_t *skip1, off_t *skip2)
+{
+ char *colon;
+
+ colon = strchr(spec, ':');
+ if (colon != NULL)
+ *colon++ = '\0';
+
+ if (expand_number(spec, skip1) < 0)
+ return (false);
+
+ if (colon != NULL)
+ return (expand_number(colon, skip2) == 0);
+
+ *skip2 = *skip1;
+ return (true);
+}
+
int
main(int argc, char *argv[])
{
@@ -86,11 +106,19 @@ main(int argc, char *argv[])
skip1 = skip2 = 0;
oflag = O_RDONLY;
- while ((ch = getopt_long(argc, argv, "+hln:sxz", long_opts, NULL)) != -1)
+ while ((ch = getopt_long(argc, argv, "+hi:ln:sxz", long_opts, NULL)) != -1)
switch (ch) {
case 'h': /* Don't follow symlinks */
oflag |= O_NOFOLLOW;
break;
+ case 'i':
+ if (!parse_iskipspec(optarg, &skip1, &skip2)) {
+ fprintf(stderr,
+ "Invalid --ignore-initial: %s\n",
+ optarg);
+ usage();
+ }
+ break;
case 'l': /* print all differences */
lflag = true;
break;
diff --git a/usr.bin/cmp/tests/cmp_test2.sh b/usr.bin/cmp/tests/cmp_test2.sh
index c513984daf8b..893ee59076c3 100755
--- a/usr.bin/cmp/tests/cmp_test2.sh
+++ b/usr.bin/cmp/tests/cmp_test2.sh
@@ -71,8 +71,13 @@ pr252542_body()
{
echo -n '1234567890' > a
echo -n 'abc567890' > b
+ echo -n 'xbc567890' > c
atf_check -s exit:0 cmp -s a b 4 3
+ atf_check -s exit:0 cmp -i 4:3 -s a b
+ atf_check -s exit:0 cmp -i 1 -s b c
atf_check -s exit:1 -o ignore cmp -z a b 4 3
+ atf_check -s exit:1 -o ignore cmp -i 4:3 -z a b
+ atf_check -s exit:1 -o ignore cmp -i 1 -z a b
}
atf_test_case skipsuff