Date: Mon, 1 Apr 2024 17:44:38 GMT From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= <des@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: dd286b0dc187 - main - cp: Improved conformance when copying directories. Message-ID: <202404011744.431HicxH074347@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=dd286b0dc187c351a9537a363840245d5505b15b commit dd286b0dc187c351a9537a363840245d5505b15b Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2024-04-01 17:28:58 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2024-04-01 17:29:31 +0000 cp: Improved conformance when copying directories. * When copying a directory, if the destination exists and is not a directory, we would previously emit an error message and exit. The correct behavior according to POSIX is to emit an error message and continue without descending further into the source directory. * When copying a directory, if the destination does not exist and we fail to create it, we would previously emit an error message and exit. The correct behavior according to POSIX is to emit an error message and continue. Whether to descend further into the source directory is explicitly left unspecified; GNU cp does not, which seems to me to be the safer and less surprising option, so let's not either. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: kevans Differential Revision: https://reviews.freebsd.org/D44577 --- bin/cp/cp.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/bin/cp/cp.c b/bin/cp/cp.c index 14d1cc2a3f75..02b879006a4f 100644 --- a/bin/cp/cp.c +++ b/bin/cp/cp.c @@ -506,9 +506,13 @@ copy(char *argv[], enum op type, int fts_options, struct stat *root_stat) * umask blocks owner writes, we fail. */ if (dne) { - if (mkdir(to.p_path, - curr->fts_statp->st_mode | S_IRWXU) < 0) - err(1, "%s", to.p_path); + mode = curr->fts_statp->st_mode | S_IRWXU; + if (mkdir(to.p_path, mode) != 0) { + warn("%s", to.p_path); + (void)fts_set(ftsp, curr, FTS_SKIP); + badcp = rval = 1; + break; + } /* * First DNE with a NULL root_stat is the root * path, so set root_stat. We can't really @@ -517,14 +521,19 @@ copy(char *argv[], enum op type, int fts_options, struct stat *root_stat) * first directory we created and use that. */ if (root_stat == NULL && - stat(to.p_path, &created_root_stat) == -1) { - err(1, "stat"); - } else if (root_stat == NULL) { - root_stat = &created_root_stat; + stat(to.p_path, &created_root_stat) != 0) { + warn("%s", to.p_path); + (void)fts_set(ftsp, curr, FTS_SKIP); + badcp = rval = 1; + break; } + if (root_stat == NULL) + root_stat = &created_root_stat; } else if (!S_ISDIR(to_stat.st_mode)) { - errno = ENOTDIR; - err(1, "%s", to.p_path); + warnc(ENOTDIR, "%s", to.p_path); + (void)fts_set(ftsp, curr, FTS_SKIP); + badcp = rval = 1; + break; } /* * Arrange to correct directory attributes later
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202404011744.431HicxH074347>