git: d002316fd7bf - main - cp: Refactor the core logic.

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Wed, 13 Dec 2023 23:41:58 UTC
The branch main has been updated by des:

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

commit d002316fd7bf0b359ea2f5518f3c10f6ad89a9ac
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2023-12-13 23:40:45 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2023-12-13 23:40:55 +0000

    cp: Refactor the core logic.
    
    Rewrite `copy_file()` so the lflag and sflag are handled as early as
    possible instead of constantly checking that they're not set and then
    handling them at the end.  This also opens the door to changing the
    failure logic at some future point (for instance, we might decide to
    fall back to copying if `errno` indicates that the file system does not
    support links).
    
    MFC after:      1 week
    Sponsored by:   Klara, Inc.
    Reviewed by:    kevans, allanjude
    Differential Revision:  https://reviews.freebsd.org/D43055
---
 bin/cp/utils.c | 121 ++++++++++++++++++++++++++++-----------------------------
 1 file changed, 60 insertions(+), 61 deletions(-)

diff --git a/bin/cp/utils.c b/bin/cp/utils.c
index 3621c89dd2f2..891360604631 100644
--- a/bin/cp/utils.c
+++ b/bin/cp/utils.c
@@ -62,6 +62,11 @@
  */
 #define BUFSIZE_SMALL (MAXPHYS)
 
+/*
+ * Prompt used in -i case.
+ */
+#define YESNO "(y/n [n]) "
+
 static ssize_t
 copy_fallback(int from_fd, int to_fd)
 {
@@ -119,7 +124,6 @@ copy_file(const FTSENT *entp, int dne)
 	 * modified by the umask.)
 	 */
 	if (!dne) {
-#define YESNO "(y/n [n]) "
 		if (nflag) {
 			if (vflag)
 				printf("%s not overwritten\n", to.p_path);
@@ -139,70 +143,68 @@ copy_file(const FTSENT *entp, int dne)
 		}
 
 		if (fflag) {
-			/*
-			 * Remove existing destination file name create a new
-			 * file.
-			 */
+			/* remove existing destination file */
 			(void)unlink(to.p_path);
-			if (!lflag && !sflag) {
-				to_fd = open(to.p_path,
-				    O_WRONLY | O_TRUNC | O_CREAT,
-				    fs->st_mode & ~(S_ISUID | S_ISGID));
-			}
-		} else if (!lflag && !sflag) {
-			/* Overwrite existing destination file name. */
-			to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0);
 		}
-	} else if (!lflag && !sflag) {
+	}
+
+	rval = 0;
+
+	if (lflag) {
+		if (link(entp->fts_path, to.p_path) != 0) {
+			warn("%s", to.p_path);
+			rval = 1;
+		}
+		goto done;
+	}
+
+	if (sflag) {
+		if (symlink(entp->fts_path, to.p_path) != 0) {
+			warn("%s", to.p_path);
+			rval = 1;
+		}
+		goto done;
+	}
+
+	if (!dne && !fflag) {
+		/* overwrite existing destination file */
+		to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0);
+	} else {
+		/* create new destination file */
 		to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT,
 		    fs->st_mode & ~(S_ISUID | S_ISGID));
 	}
-
-	if (!lflag && !sflag && to_fd == -1) {
+	if (to_fd == -1) {
 		warn("%s", to.p_path);
 		rval = 1;
 		goto done;
 	}
 
-	rval = 0;
-
-	if (!lflag && !sflag) {
-		wtotal = 0;
-		do {
-			if (use_copy_file_range) {
-				wcount = copy_file_range(from_fd, NULL,
-				    to_fd, NULL, SSIZE_MAX, 0);
-				if (wcount < 0 && errno == EINVAL) {
-					/* Prob a non-seekable FD */
-					use_copy_file_range = 0;
-				}
-			}
-			if (!use_copy_file_range) {
-				wcount = copy_fallback(from_fd, to_fd);
-			}
-			wtotal += wcount;
-			if (info) {
-				info = 0;
-				(void)fprintf(stderr,
-				    "%s -> %s %3d%%\n",
-				    entp->fts_path, to.p_path,
-				    cp_pct(wtotal, fs->st_size));
+	wtotal = 0;
+	do {
+		if (use_copy_file_range) {
+			wcount = copy_file_range(from_fd, NULL,
+			    to_fd, NULL, SSIZE_MAX, 0);
+			if (wcount < 0 && errno == EINVAL) {
+				/* probably a non-seekable descriptor */
+				use_copy_file_range = 0;
 			}
-		} while (wcount > 0);
-		if (wcount < 0) {
-			warn("%s", entp->fts_path);
-			rval = 1;
 		}
-	} else if (lflag) {
-		if (link(entp->fts_path, to.p_path)) {
-			warn("%s", to.p_path);
-			rval = 1;
+		if (!use_copy_file_range) {
+			wcount = copy_fallback(from_fd, to_fd);
 		}
-	} else if (sflag) {
-		if (symlink(entp->fts_path, to.p_path)) {
-			warn("%s", to.p_path);
-			rval = 1;
+		wtotal += wcount;
+		if (info) {
+			info = 0;
+			(void)fprintf(stderr,
+			    "%s -> %s %3d%%\n",
+			    entp->fts_path, to.p_path,
+			    cp_pct(wtotal, fs->st_size));
 		}
+	} while (wcount > 0);
+	if (wcount < 0) {
+		warn("%s", entp->fts_path);
+		rval = 1;
 	}
 
 	/*
@@ -211,16 +213,13 @@ copy_file(const FTSENT *entp, int dne)
 	 * or its contents might be irreplaceable.  It would only be safe
 	 * to remove it if we created it and its length is 0.
 	 */
-
-	if (!lflag && !sflag) {
-		if (pflag && setfile(fs, to_fd))
-			rval = 1;
-		if (pflag && preserve_fd_acls(from_fd, to_fd) != 0)
-			rval = 1;
-		if (close(to_fd)) {
-			warn("%s", to.p_path);
-			rval = 1;
-		}
+	if (pflag && setfile(fs, to_fd))
+		rval = 1;
+	if (pflag && preserve_fd_acls(from_fd, to_fd) != 0)
+		rval = 1;
+	if (close(to_fd)) {
+		warn("%s", to.p_path);
+		rval = 1;
 	}
 
 done: