diff --git a/usr.bin/cmp/cmp.1 b/usr.bin/cmp/cmp.1 --- a/usr.bin/cmp/cmp.1 +++ b/usr.bin/cmp/cmp.1 @@ -40,7 +40,7 @@ .Sh SYNOPSIS .Nm .Op Fl l | s | x -.Op Fl hz +.Op Fl bhz .Op Fl -ignore-initial Ns Cm = Ns Ar num1 Ns Op :num2 .Op Fl -bytes Ns Cm = Ns Ar num .Ar file1 file2 @@ -59,6 +59,8 @@ .Pp The following options are available: .Bl -tag -width indent +.It Fl b , Fl -print-bytes +Print each byte when a difference is found. .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 @@ -187,6 +189,7 @@ .St -p1003.2 compatible. The +.Fl b , .Fl h , .Fl i , .Fl n , diff --git a/usr.bin/cmp/cmp.c b/usr.bin/cmp/cmp.c --- a/usr.bin/cmp/cmp.c +++ b/usr.bin/cmp/cmp.c @@ -62,10 +62,11 @@ #include "extern.h" -bool lflag, sflag, xflag, zflag; +bool bflag, lflag, sflag, xflag, zflag; static const struct option long_opts[] = { + {"print-bytes", no_argument, NULL, 'b'}, {"ignore-initial", required_argument, NULL, 'i'}, {"verbose", no_argument, NULL, 'l'}, {"bytes", required_argument, NULL, 'n'}, @@ -106,8 +107,11 @@ skip1 = skip2 = 0; oflag = O_RDONLY; - while ((ch = getopt_long(argc, argv, "+hi:ln:sxz", long_opts, NULL)) != -1) + while ((ch = getopt_long(argc, argv, "+bhi:ln:sxz", long_opts, NULL)) != -1) switch (ch) { + case 'b': /* Print bytes */ + bflag = true; + break; case 'h': /* Don't follow symlinks */ oflag |= O_NOFOLLOW; break; diff --git a/usr.bin/cmp/extern.h b/usr.bin/cmp/extern.h --- a/usr.bin/cmp/extern.h +++ b/usr.bin/cmp/extern.h @@ -42,7 +42,7 @@ 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 diffmsg(const char *, const char *, off_t, off_t, int, int); void eofmsg(const char *); -extern bool lflag, sflag, xflag, zflag; +extern bool bflag, lflag, sflag, xflag, zflag; diff --git a/usr.bin/cmp/link.c b/usr.bin/cmp/link.c --- a/usr.bin/cmp/link.c +++ b/usr.bin/cmp/link.c @@ -82,10 +82,14 @@ (long long)byte - 1, ch, *p2); } else if (lflag) { dfound = 1; - (void)printf("%6lld %3o %3o\n", - (long long)byte, ch, *p2); + if (bflag) + (void)printf("%6lld %3o %c %3o %c\n", + (long long)byte, ch, ch, *p2, *p2); + else + (void)printf("%6lld %3o %3o\n", + (long long)byte, ch, *p2); } else - diffmsg(file1, file2, byte, 1); + diffmsg(file1, file2, byte, 1, ch, *p2); /* NOTREACHED */ } byte++; diff --git a/usr.bin/cmp/misc.c b/usr.bin/cmp/misc.c --- a/usr.bin/cmp/misc.c +++ b/usr.bin/cmp/misc.c @@ -56,10 +56,20 @@ } void -diffmsg(const char *file1, const char *file2, off_t byte, off_t line) +diffmsg(const char *file1, const char *file2, off_t byte, off_t line, + int b1, int b2) { - if (!sflag) + if (sflag) + goto out; + + if (bflag) { + (void)printf("%s %s differ: char %lld, line %lld is %3o %c %3o %c\n", + file1, file2, (long long)byte, (long long)line, b1, b1, + b2, b2); + } else { (void)printf("%s %s differ: char %lld, line %lld\n", file1, file2, (long long)byte, (long long)line); + } +out: exit(DIFF_EXIT); } diff --git a/usr.bin/cmp/regular.c b/usr.bin/cmp/regular.c --- a/usr.bin/cmp/regular.c +++ b/usr.bin/cmp/regular.c @@ -127,10 +127,14 @@ (long long)byte - 1, ch, *p2); } else if (lflag) { dfound = 1; - (void)printf("%6lld %3o %3o\n", - (long long)byte, ch, *p2); + if (bflag) + (void)printf("%6lld %3o %c %3o %c\n", + (long long)byte, ch, ch, *p2, *p2); + else + (void)printf("%6lld %3o %3o\n", + (long long)byte, ch, *p2); } else - diffmsg(file1, file2, byte, line); + diffmsg(file1, file2, byte, line, ch, *p2); /* NOTREACHED */ } if (ch == '\n') diff --git a/usr.bin/cmp/special.c b/usr.bin/cmp/special.c --- a/usr.bin/cmp/special.c +++ b/usr.bin/cmp/special.c @@ -88,10 +88,15 @@ (long long)byte - 1, ch1, ch2); } else if (lflag) { dfound = 1; - (void)printf("%6lld %3o %3o\n", - (long long)byte, ch1, ch2); + if (bflag) + (void)printf("%6lld %3o %c %3o %c\n", + (long long)byte, ch1, ch1, ch2, + ch2); + else + (void)printf("%6lld %3o %3o\n", + (long long)byte, ch1, ch2); } else { - diffmsg(file1, file2, byte, line); + diffmsg(file1, file2, byte, line, ch1, ch2); /* NOTREACHED */ } } diff --git a/usr.bin/cmp/tests/Makefile b/usr.bin/cmp/tests/Makefile --- a/usr.bin/cmp/tests/Makefile +++ b/usr.bin/cmp/tests/Makefile @@ -2,9 +2,14 @@ .include +PACKAGE= tests + ATF_TESTS_SH+= cmp_test2 NETBSD_ATF_TESTS_SH= cmp_test +${PACKAGE}FILES+= b_flag.out +${PACKAGE}FILES+= bl_flag.out + .include .include diff --git a/usr.bin/cmp/tests/b_flag.out b/usr.bin/cmp/tests/b_flag.out new file mode 100644 --- /dev/null +++ b/usr.bin/cmp/tests/b_flag.out @@ -0,0 +1 @@ +a b differ: char 3, line 1 is 143 c 144 d diff --git a/usr.bin/cmp/tests/bl_flag.out b/usr.bin/cmp/tests/bl_flag.out new file mode 100644 --- /dev/null +++ b/usr.bin/cmp/tests/bl_flag.out @@ -0,0 +1 @@ + 3 143 c 144 d diff --git a/usr.bin/cmp/tests/cmp_test2.sh b/usr.bin/cmp/tests/cmp_test2.sh --- a/usr.bin/cmp/tests/cmp_test2.sh +++ b/usr.bin/cmp/tests/cmp_test2.sh @@ -118,6 +118,22 @@ atf_check -s exit:1 -o ignore -x "cat a | cmp -sn 5 b -" } +atf_test_case bflag +bflag_head() +{ + atf_set "descr" "Test cmp(1) -b (print bytes)" +} +bflag_body() +{ + echo -n "abcd" > a + echo -n "abdd" > b + + atf_check -s exit:1 -o file:$(atf_get_srcdir)/b_flag.out \ + cmp -b a b + atf_check -s exit:1 -o file:$(atf_get_srcdir)/bl_flag.out \ + cmp -bl a b +} + atf_init_test_cases() { atf_add_test_case special @@ -125,4 +141,5 @@ atf_add_test_case pr252542 atf_add_test_case skipsuff atf_add_test_case limit + atf_add_test_case bflag }