From nobody Wed Mar 09 21:22:48 2022 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id C0F8C19F4A45; Wed, 9 Mar 2022 21:22:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KDQCD3JXRz3nVk; Wed, 9 Mar 2022 21:22:48 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1646860968; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=sB8n/psEus8jS74QPEOa8WzkT2gI2YBTdvIqL7vcDZ8=; b=tG2s1scDM/DBLj4gZS+cKJNbn3nzcvOKWIFPRd/8yodG8khO/XeiV1HJSaOrB79wmFW40c 4iTWsGPng7t+0NnVudHYdAdyvAfEleUqAUH6JyMkRGrtsKqAPw1dw7TfdshlVYQyxlUzaC jwl4iEocDsHy5L4cvWfbNMP9zOjy1fgBhFhgV/87gXmsxon4fdTNUWCRvrivKmYN0TmT2V 0sI2RqgIM5Btjpo5J9LSlAaL9D2sE/eq14uRgmIVw54nnTmDqj+P0ry08tXZMAu/nU+I5d B6hIk4RSoMXejswYlTlG5M+D0nGWM5o2xgTwJP3R4nzAA4A5Vi/VHBEsYgbLSg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 2AE9D18799; Wed, 9 Mar 2022 21:22:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 229LMmln003337; Wed, 9 Mar 2022 21:22:48 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 229LMmQs003336; Wed, 9 Mar 2022 21:22:48 GMT (envelope-from git) Date: Wed, 9 Mar 2022 21:22:48 GMT Message-Id: <202203092122.229LMmQs003336@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kyle Evans Subject: git: f8e07f2f9685 - stable/13 - cp: fix -R with links List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: f8e07f2f968587e58e20755b4aa5c90a0a09aec3 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1646860968; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=sB8n/psEus8jS74QPEOa8WzkT2gI2YBTdvIqL7vcDZ8=; b=x+Xwyqy4myi3YbrLeJlB/iK9PgjbRE3VJBd5puaaDPxgbrJ6HwCMIjDMfa8wxfextSwKUQ gZ/AYRHxsBq0cRiCkrs7eatZAkZE0vFMXWJTXV4E0EHkfuq+z9Ac5FTkeoEW1PlNyavCK3 kbr9ETOdBWZHdPiuyECjM03cRuwKMqdwbz3D0F9ZTsoQ2xi90SGYX6Kv0DN+OmNfV9RNF0 FIvxQkYGwPtEdF3NPr475yOr8HYxCrAD7CehxPUH4S8bOwKMYIk2+gYU+T4cA7x9BMdrx2 zhrr1WyYHPF5GeLIn6zV04Txil/E7TZMdW9Tb+LHzEqkRJeaiefnIsjtr5qehw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1646860968; a=rsa-sha256; cv=none; b=HSbApImbJ39LCNfwdsuY7731NRSyqj3cHoR06PsCf+BPVvrQHNaNlyp/tZ77ZwYqThomnD FIHJ6wXDHsfFV82rI57f/wRXasSd/ZVmk6tIlPeGDRNVQTndNLldmVBXHDNTq7CaAGbmW8 SWZ6te6FB+GCepHUe7qj7/j2yTccIUTQ+zRkU+nlpTVjOGoVgM1bolgnsRyyZVqBA6WNEA VUM/zHdlHrAoDqvxq/ekfJ906+AnxFzPlU+LC5ECfMLTK/pdkV74wpe+4JpISWfHFx8ZQ2 jLEIrm5ezd20QU5Hte5nHi3PetfOOrji7NQLdEBKnFi/flQ7B52Mh+b5UqTGuw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=f8e07f2f968587e58e20755b4aa5c90a0a09aec3 commit f8e07f2f968587e58e20755b4aa5c90a0a09aec3 Author: Kyle Evans AuthorDate: 2022-01-27 18:02:17 +0000 Commit: Kyle Evans CommitDate: 2022-03-09 21:21:58 +0000 cp: fix -R with links The traversal was previously not properly honoring -H/-L/-P. Notably, we should not have been resolving symlinks encountered during traversal when either -H or -P are specified. (cherry picked from commit 33ad990ce974be50abdc25427b0f365699d83a34) --- bin/cp/cp.c | 23 ++++++++++++++---- bin/cp/tests/cp_test.sh | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/bin/cp/cp.c b/bin/cp/cp.c index 3a23394df35d..14007cf1ee66 100644 --- a/bin/cp/cp.c +++ b/bin/cp/cp.c @@ -86,7 +86,7 @@ static char emptystring[] = ""; PATH_T to = { to.p_path, emptystring, "" }; int fflag, iflag, lflag, nflag, pflag, sflag, vflag; -static int Rflag, rflag; +static int Hflag, Lflag, Rflag, rflag; volatile sig_atomic_t info; enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE }; @@ -99,11 +99,10 @@ main(int argc, char *argv[]) { struct stat to_stat, tmp_stat; enum op type; - int Hflag, Lflag, ch, fts_options, r, have_trailing_slash; + int ch, fts_options, r, have_trailing_slash; char *target; fts_options = FTS_NOCHDIR | FTS_PHYSICAL; - Hflag = Lflag = 0; while ((ch = getopt(argc, argv, "HLPRafilnprsvx")) != -1) switch (ch) { case 'H': @@ -262,6 +261,22 @@ main(int argc, char *argv[]) exit (copy(argv, type, fts_options)); } +/* Does the right thing based on -R + -H/-L/-P */ +static int +copy_stat(const char *path, struct stat *sb) +{ + + /* + * For -R -H/-P, we need to lstat() instead; copy() cares about the link + * itself rather than the target if we're not following links during the + * traversal. + */ + if (!Rflag || Lflag) + return (stat(path, sb)); + return (lstat(path, sb)); +} + + static int copy(char *argv[], enum op type, int fts_options) { @@ -392,7 +407,7 @@ copy(char *argv[], enum op type, int fts_options) } /* Not an error but need to remember it happened. */ - if (stat(to.p_path, &to_stat) == -1) + if (copy_stat(to.p_path, &to_stat) == -1) dne = 1; else { if (to_stat.st_dev == curr->fts_statp->st_dev && diff --git a/bin/cp/tests/cp_test.sh b/bin/cp/tests/cp_test.sh index 753e69f2d619..fa2bf82e1478 100755 --- a/bin/cp/tests/cp_test.sh +++ b/bin/cp/tests/cp_test.sh @@ -43,6 +43,21 @@ basic_body() check_size baz 4 } +atf_test_case basic_symlink +basic_symlink_body() +{ + echo "foo" > bar + ln -s bar baz + + atf_check cp baz foo + atf_check test '!' -L foo + + atf_check -e inline:"cp: baz and baz are identical (not copied).\n" \ + -s exit:1 cp baz baz + atf_check -e inline:"cp: bar and baz are identical (not copied).\n" \ + -s exit:1 cp baz bar +} + atf_test_case chrdev chrdev_body() { @@ -57,8 +72,57 @@ chrdev_body() check_size trunc 0 } +recursive_link_setup() +{ + extra_cpflag=$1 + + mkdir -p foo/bar + ln -s bar foo/baz + + mkdir foo-mirror + eval "cp -R $extra_cpflag foo foo-mirror" +} + +atf_test_case recursive_link_dflt +recursive_link_dflt_body() +{ + recursive_link_setup + + # -P is the default, so this should work and preserve the link. + atf_check cp -R foo foo-mirror + atf_check test -L foo-mirror/foo/baz +} + +atf_test_case recursive_link_Hflag +recursive_link_Hflag_body() +{ + recursive_link_setup + + # -H will not follow either, so this should also work and preserve the + # link. + atf_check cp -RH foo foo-mirror + atf_check test -L foo-mirror/foo/baz +} + +atf_test_case recursive_link_Lflag +recursive_link_Lflag_body() +{ + recursive_link_setup -L + + # -L will work, but foo/baz ends up expanded to a directory. + atf_check test -d foo-mirror/foo/baz -a \ + '(' ! -L foo-mirror/foo/baz ')' + atf_check cp -RL foo foo-mirror + atf_check test -d foo-mirror/foo/baz -a \ + '(' ! -L foo-mirror/foo/baz ')' +} + atf_init_test_cases() { atf_add_test_case basic + atf_add_test_case basic_symlink atf_add_test_case chrdev + atf_add_test_case recursive_link_dflt + atf_add_test_case recursive_link_Hflag + atf_add_test_case recursive_link_Lflag }