The branch stable/14 has been updated by des:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=02a8a4e4eb25cb51d244ef835146108f01bc249e

commit 02a8a4e4eb25cb51d244ef835146108f01bc249e
Author:     Dag-Erling Smørgrav <d...@freebsd.org>
AuthorDate: 2024-10-09 12:08:42 +0000
Commit:     Dag-Erling Smørgrav <d...@freebsd.org>
CommitDate: 2024-10-15 05:25:17 +0000

    cmp: Style and type issues.
    
    MFC after:      3 days
    Sponsored by:   Klara, Inc.
    Reviewed by:    0mp, markj
    Differential Revision:  https://reviews.freebsd.org/D47019
    
    (cherry picked from commit d350e8d795d53dbc58ea428f76355cf5e28f6116)
    
    cmp: Check the status of stdout.
    
    POSIX requires us to print an error message and exit non-zero if
    writing to stdout fails.  This can only happen if sflag is unset.
    
    MFC after:      3 days
    Sponsored by:   Klara, Inc.
    Reviewed by:    markj
    Differential Revision:  https://reviews.freebsd.org/D47020
    
    (cherry picked from commit 3c37828ee1874754e1c5e96268016113c1e02ba2)
---
 usr.bin/cmp/cmp.c              | 29 +++++++++++++++-----------
 usr.bin/cmp/extern.h           |  6 +++---
 usr.bin/cmp/link.c             | 18 ++++++++++-------
 usr.bin/cmp/misc.c             | 10 +++------
 usr.bin/cmp/regular.c          | 36 ++++++++++++++++++---------------
 usr.bin/cmp/special.c          | 19 ++++++++++-------
 usr.bin/cmp/tests/cmp_test2.sh | 46 ++++++++++++++++++++++++++++++++++--------
 7 files changed, 104 insertions(+), 60 deletions(-)

diff --git a/usr.bin/cmp/cmp.c b/usr.bin/cmp/cmp.c
index 56775e73ffa2..d6eb53620126 100644
--- a/usr.bin/cmp/cmp.c
+++ b/usr.bin/cmp/cmp.c
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)cmp.c     8.3 (Berkeley) 4/2/94";
 #include <fcntl.h>
 #include <getopt.h>
 #include <nl_types.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -79,7 +80,6 @@ volatile sig_atomic_t info;
 static void
 siginfo(int signo)
 {
-
        info = signo;
 }
 #endif
@@ -113,8 +113,9 @@ main(int argc, char *argv[])
        int ch, fd1, fd2, oflag;
        bool special;
        const char *file1, *file2;
+       int ret;
 
-       limit = skip1 = skip2 = 0;
+       limit = skip1 = skip2 = ret = 0;
        oflag = O_RDONLY;
        while ((ch = getopt_long(argc, argv, "+bhi:ln:sxz", long_opts, NULL)) 
!= -1)
                switch (ch) {
@@ -212,8 +213,8 @@ main(int argc, char *argv[])
 
        if (fd1 == -1) {
                if (fd2 == -1) {
-                       c_link(file1, skip1, file2, skip2, limit);
-                       exit(0);
+                       ret = c_link(file1, skip1, file2, skip2, limit);
+                       goto end;
                } else if (!sflag)
                        errx(ERR_EXIT, "%s: Not a symbolic link", file2);
                else
@@ -252,19 +253,23 @@ main(int argc, char *argv[])
 #ifdef SIGINFO
        (void)signal(SIGINFO, siginfo);
 #endif
-       if (special)
-               c_special(fd1, file1, skip1, fd2, file2, skip2, limit);
-       else {
+       if (special) {
+               ret = c_special(fd1, file1, skip1, fd2, file2, skip2, limit);
+       } else {
                if (zflag && sb1.st_size != sb2.st_size) {
                        if (!sflag)
-                               (void) printf("%s %s differ: size\n",
+                               (void)printf("%s %s differ: size\n",
                                    file1, file2);
-                       exit(DIFF_EXIT);
+                       ret = DIFF_EXIT;
+               } else {
+                       ret = c_regular(fd1, file1, skip1, sb1.st_size,
+                           fd2, file2, skip2, sb2.st_size, limit);
                }
-               c_regular(fd1, file1, skip1, sb1.st_size,
-                   fd2, file2, skip2, sb2.st_size, limit);
        }
-       exit(0);
+end:
+       if (!sflag && fflush(stdout) != 0)
+               err(ERR_EXIT, "stdout");
+       exit(ret);
 }
 
 static void
diff --git a/usr.bin/cmp/extern.h b/usr.bin/cmp/extern.h
index e1327df949c3..bca82eab2ac4 100644
--- a/usr.bin/cmp/extern.h
+++ b/usr.bin/cmp/extern.h
@@ -36,10 +36,10 @@
 #define DIFF_EXIT      1
 #define ERR_EXIT       2       /* error exit code */
 
-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,
+int    c_link(const char *, off_t, const char *, off_t, off_t);
+int    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);
+int    c_special(int, const char *, off_t, int, const char *, off_t, off_t);
 void   diffmsg(const char *, const char *, off_t, off_t, int, int);
 void   eofmsg(const char *);
 
diff --git a/usr.bin/cmp/link.c b/usr.bin/cmp/link.c
index 550273cb471a..070f52986d50 100644
--- a/usr.bin/cmp/link.c
+++ b/usr.bin/cmp/link.c
@@ -28,6 +28,7 @@
 
 #include <sys/cdefs.h>
 #include <sys/types.h>
+
 #include <err.h>
 #include <limits.h>
 #include <stdbool.h>
@@ -37,13 +38,14 @@
 
 #include "extern.h"
 
-void
+int
 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;
-       int dfound, len1, len2;
+       ssize_t len1, len2;
+       int dfound;
        off_t byte;
        u_char ch;
 
@@ -86,15 +88,17 @@ c_link(const char *file1, off_t skip1, const char *file2, 
off_t skip2,
                                else
                                        (void)printf("%6lld %3o %3o\n",
                                            (long long)byte, ch, *p2);
-                       } else
+                       } else {
                                diffmsg(file1, file2, byte, 1, ch, *p2);
-                               /* NOTREACHED */
+                               return (DIFF_EXIT);
+                       }
                }
                byte++;
        }
 
-       if (*p1 || *p2)
+       if (*p1 || *p2) {
                eofmsg (*p1 ? file2 : file1);
-       if (dfound)
-               exit(DIFF_EXIT);
+               return (DIFF_EXIT);
+       }
+       return (dfound ? DIFF_EXIT : 0);
 }
diff --git a/usr.bin/cmp/misc.c b/usr.bin/cmp/misc.c
index 1924025a3a5d..d96654c57074 100644
--- a/usr.bin/cmp/misc.c
+++ b/usr.bin/cmp/misc.c
@@ -50,17 +50,15 @@ eofmsg(const char *file)
 {
        if (!sflag)
                warnx("EOF on %s", file);
-       exit(DIFF_EXIT);
 }
 
 void
 diffmsg(const char *file1, const char *file2, off_t byte, off_t line,
     int b1, int b2)
 {
-       if (sflag)
-               goto out;
-
-       if (bflag) {
+       if (sflag) {
+               /* nothing */
+       } else 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);
@@ -68,6 +66,4 @@ diffmsg(const char *file1, const char *file2, off_t byte, 
off_t line,
                (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
index fbe62bb75602..7f7afc5862dd 100644
--- a/usr.bin/cmp/regular.c
+++ b/usr.bin/cmp/regular.c
@@ -44,6 +44,7 @@ static char sccsid[] = "@(#)regular.c 8.3 (Berkeley) 4/2/94";
 #include <err.h>
 #include <limits.h>
 #include <signal.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -56,7 +57,7 @@ static void segv_handler(int);
 
 #define ROUNDPAGE(i) ((i) & ~pagemask)
 
-void
+int
 c_regular(int fd1, const char *file1, off_t skip1, off_t len1,
     int fd2, const char *file2, off_t skip2, off_t len2, off_t limit)
 {
@@ -68,15 +69,19 @@ c_regular(int fd1, const char *file1, off_t skip1, off_t 
len1,
        size_t pagesize;
        int dfound;
 
-       if (skip1 > len1)
+       if (skip1 > len1) {
                eofmsg(file1);
+               return (DIFF_EXIT);
+       }
        len1 -= skip1;
-       if (skip2 > len2)
+       if (skip2 > len2) {
                eofmsg(file2);
+               return (DIFF_EXIT);
+       }
        len2 -= skip2;
 
        if (sflag && len1 != len2)
-               exit(DIFF_EXIT);
+               return (DIFF_EXIT);
 
        pagesize = getpagesize();
        pagemask = (off_t)pagesize - 1;
@@ -88,14 +93,12 @@ c_regular(int fd1, const char *file1, off_t skip1, off_t 
len1,
                length = MIN(length, limit);
 
        if ((m1 = remmap(NULL, fd1, off1)) == NULL) {
-               c_special(fd1, file1, skip1, fd2, file2, skip2, limit);
-               return;
+               return (c_special(fd1, file1, skip1, fd2, file2, skip2, limit));
        }
 
        if ((m2 = remmap(NULL, fd2, off2)) == NULL) {
                munmap(m1, MMAP_CHUNK);
-               c_special(fd1, file1, skip1, fd2, file2, skip2, limit);
-               return;
+               return (c_special(fd1, file1, skip1, fd2, file2, skip2, limit));
        }
 
        if (caph_rights_limit(fd1, cap_rights_init(&rights, CAP_MMAP_R)) < 0)
@@ -126,21 +129,21 @@ c_regular(int fd1, const char *file1, off_t skip1, off_t 
len1,
                }
 #endif
                if ((ch = *p1) != *p2) {
+                       dfound = 1;
                        if (xflag) {
-                               dfound = 1;
                                (void)printf("%08llx %02x %02x\n",
                                    (long long)byte - 1, ch, *p2);
                        } else if (lflag) {
-                               dfound = 1;
                                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
+                       } else {
                                diffmsg(file1, file2, byte, line, ch, *p2);
-                               /* NOTREACHED */
+                               return (DIFF_EXIT);
+                       }
                }
                if (ch == '\n')
                        ++line;
@@ -167,10 +170,11 @@ c_regular(int fd1, const char *file1, off_t skip1, off_t 
len1,
        if (sigaction(SIGSEGV, &oact, NULL))
                err(ERR_EXIT, "sigaction()");
 
-       if (len1 != len2)
-               eofmsg (len1 > len2 ? file2 : file1);
-       if (dfound)
-               exit(DIFF_EXIT);
+       if (len1 != len2) {
+               eofmsg(len1 > len2 ? file2 : file1);
+               return (DIFF_EXIT);
+       }
+       return (dfound ? DIFF_EXIT : 0);
 }
 
 static u_char *
diff --git a/usr.bin/cmp/special.c b/usr.bin/cmp/special.c
index 3da54fde24e4..98d18c019d88 100644
--- a/usr.bin/cmp/special.c
+++ b/usr.bin/cmp/special.c
@@ -40,12 +40,13 @@ static char sccsid[] = "@(#)special.c       8.3 (Berkeley) 
4/2/94";
 
 #include <capsicum_helpers.h>
 #include <err.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 
 #include "extern.h"
 
-void
+int
 c_special(int fd1, const char *file1, off_t skip1,
     int fd2, const char *file2, off_t skip2, off_t limit)
 {
@@ -104,7 +105,7 @@ c_special(int fd1, const char *file1, off_t skip1,
                                            (long long)byte, ch1, ch2);
                        } else {
                                diffmsg(file1, file2, byte, line, ch1, ch2);
-                               /* NOTREACHED */
+                               return (DIFF_EXIT);
                        }
                }
                if (ch1 == '\n')
@@ -116,13 +117,17 @@ eof:      if (ferror(fp1))
        if (ferror(fp2))
                err(ERR_EXIT, "%s", file2);
        if (feof(fp1)) {
-               if (!feof(fp2))
+               if (!feof(fp2)) {
                        eofmsg(file1);
-       } else
-               if (feof(fp2))
+                       return (DIFF_EXIT);
+               }
+       } else {
+               if (feof(fp2)) {
                        eofmsg(file2);
+                       return (DIFF_EXIT);
+               }
+       }
        fclose(fp2);
        fclose(fp1);
-       if (dfound)
-               exit(DIFF_EXIT);
+       return (dfound ? DIFF_EXIT : 0);
 }
diff --git a/usr.bin/cmp/tests/cmp_test2.sh b/usr.bin/cmp/tests/cmp_test2.sh
index ca4f6d7cf848..2ec6071851d3 100755
--- a/usr.bin/cmp/tests/cmp_test2.sh
+++ b/usr.bin/cmp/tests/cmp_test2.sh
@@ -31,12 +31,12 @@ special_head() {
 special_body() {
        echo 0123456789abcdef > a
        echo 0123456789abcdeg > b
-       atf_check -s exit:0 -o empty -e empty -x "cat a | cmp a -"
-       atf_check -s exit:0 -o empty -e empty -x "cat a | cmp - a"
-       atf_check -s exit:1 -o not-empty -e empty -x "cat b | cmp a -"
-       atf_check -s exit:1 -o not-empty -e empty -x "cat b | cmp - a"
+       atf_check -s exit:0 -o empty -e empty cmp a - <a
+       atf_check -s exit:0 -o empty -e empty cmp - a <a
+       atf_check -s exit:1 -o not-empty -e empty cmp a - <b
+       atf_check -s exit:1 -o not-empty -e empty cmp - a <b
 
-       atf_check -s exit:0 -o empty -e empty -x "cmp a a <&-"
+       atf_check -s exit:0 -o empty -e empty cmp a a <&-
 }
 
 atf_test_case symlink
@@ -112,9 +112,9 @@ limit_body()
 
        # 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_check -s exit:0 -e empty cmp -sn 4 b - <a
+       atf_check -s exit:0 -e empty cmp -sn 3 b - <a
+       atf_check -s exit:1 -o ignore cmp -sn 5 b - <a
 }
 
 atf_test_case bflag
@@ -133,6 +133,35 @@ bflag_body()
            cmp -bl a b
 }
 
+# Helper for stdout test case
+atf_check_stdout()
+{
+       (
+               trap "" PIPE
+               cmp "$@" 2>stderr
+               echo $? >result
+       ) | true
+       atf_check -o inline:"2\n" cat result
+       atf_check -o match:"stdout" cat stderr
+}
+
+atf_test_case stdout
+stdout_head()
+{
+       atf_set descr "Failure to write to stdout"
+}
+stdout_body()
+{
+       echo a >a
+       echo b >b
+       atf_check_stdout a b
+       atf_check_stdout - b <a
+       atf_check_stdout a - <b
+       ln -s a alnk
+       ln -s b blnk
+       atf_check_stdout -h alnk blnk
+}
+
 atf_init_test_cases()
 {
        atf_add_test_case special
@@ -141,4 +170,5 @@ atf_init_test_cases()
        atf_add_test_case skipsuff
        atf_add_test_case limit
        atf_add_test_case bflag
+       atf_add_test_case stdout
 }

Reply via email to