git: 11b0b75a9fba - stable/13 - cmp: Style and type issues.

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Tue, 15 Oct 2024 06:30:29 UTC
The branch stable/13 has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=11b0b75a9fba14d8f051c8d5bf30827ed9d8d580

commit 11b0b75a9fba14d8f051c8d5bf30827ed9d8d580
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2024-10-09 12:08:42 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2024-10-15 05:26:24 +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 01ff26b2b8bc..53e21474da59 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
 }