git: 17997507040c - stable/13 - cp: Clarify an obscure comment.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 27 Apr 2024 14:58:48 UTC
The branch stable/13 has been updated by des:
URL: https://cgit.FreeBSD.org/src/commit/?id=17997507040c4ad1c6a25ce93c3981ee19ce28c0
commit 17997507040c4ad1c6a25ce93c3981ee19ce28c0
Author: Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2024-04-17 01:36:22 +0000
Commit: Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2024-04-27 14:58:40 +0000
cp: Clarify an obscure comment.
MFC after: 1 week
Sponsored by: Klara, Inc.
Reviewed by: allanjude
Differential Revision: https://reviews.freebsd.org/D44805
(cherry picked from commit 64d6925d1901637125f9f739282e72c992657dc8)
cp: Additional sanity check.
Once we've successfully opened the file we've been asked to copy, check
that it's of the same type as FTS told us it was.
MFC after: 1 week
Sponsored by: Klara, Inc.
Reviewed by: allanjude, markj
Differential Revision: https://reviews.freebsd.org/D44806
(cherry picked from commit 9075d4cfad5b339aabdf8033623a2164898c2786)
cp: Use warnc().
MFC after: 1 week
Sponsored by: Klara, Inc.
(cherry picked from commit f070188c3ad6b87ee9ce220b21718333d1bd9d52)
---
bin/cp/cp.c | 13 +++++++++----
bin/cp/utils.c | 27 ++++++++++++++++++++-------
2 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/bin/cp/cp.c b/bin/cp/cp.c
index af7d5ffac398..a8c57308ae96 100644
--- a/bin/cp/cp.c
+++ b/bin/cp/cp.c
@@ -316,8 +316,7 @@ copy(char *argv[], enum op type, int fts_options, struct stat *root_stat)
case FTS_NS:
case FTS_DNR:
case FTS_ERR:
- warnx("%s: %s",
- curr->fts_path, strerror(curr->fts_errno));
+ warnc(curr->fts_errno, "%s", curr->fts_path);
badcp = rval = 1;
continue;
case FTS_DC: /* Warn, continue. */
@@ -491,13 +490,19 @@ copy(char *argv[], enum op type, int fts_options, struct stat *root_stat)
switch (curr->fts_statp->st_mode & S_IFMT) {
case S_IFLNK:
- /* Catch special case of a non-dangling symlink. */
if ((fts_options & FTS_LOGICAL) ||
((fts_options & FTS_COMFOLLOW) &&
curr->fts_level == 0)) {
+ /*
+ * We asked FTS to follow links but got
+ * here anyway, which means the target is
+ * nonexistent or inaccessible. Let
+ * copy_file() deal with the error.
+ */
if (copy_file(curr, dne))
badcp = rval = 1;
- } else {
+ } else {
+ /* Copy the link. */
if (copy_link(curr, !dne))
badcp = rval = 1;
}
diff --git a/bin/cp/utils.c b/bin/cp/utils.c
index 0bb5157e3f57..9f6ef888c7ea 100644
--- a/bin/cp/utils.c
+++ b/bin/cp/utils.c
@@ -106,21 +106,34 @@ copy_fallback(int from_fd, int to_fd)
int
copy_file(const FTSENT *entp, int dne)
{
- struct stat *fs;
+ struct stat sb, *fs;
ssize_t wcount;
off_t wtotal;
int ch, checkch, from_fd, rval, to_fd;
int use_copy_file_range = 1;
+ fs = entp->fts_statp;
from_fd = to_fd = -1;
- if (!lflag && !sflag &&
- (from_fd = open(entp->fts_path, O_RDONLY, 0)) == -1) {
- warn("%s", entp->fts_path);
- return (1);
+ if (!lflag && !sflag) {
+ if ((from_fd = open(entp->fts_path, O_RDONLY, 0)) < 0 ||
+ fstat(from_fd, &sb) != 0) {
+ warn("%s", entp->fts_path);
+ return (1);
+ }
+ /*
+ * Check that the file hasn't been replaced with one of a
+ * different type. This can happen if we've been asked to
+ * copy something which is actively being modified and
+ * lost the race, or if we've been asked to copy something
+ * like /proc/X/fd/Y which stat(2) reports as S_IFREG but
+ * is actually something else once you open it.
+ */
+ if ((sb.st_mode & S_IFMT) != (fs->st_mode & S_IFMT)) {
+ warnx("%s: File changed", entp->fts_path);
+ return (1);
+ }
}
- fs = entp->fts_statp;
-
/*
* If the file exists and we're interactive, verify with the user.
* If the file DNE, set the mode to be the from file, minus setuid