diff options
author | Cameron Katri <me@cameronkatri.com> | 2022-02-23 18:55:13 +0000 |
---|---|---|
committer | Kyle Evans <kevans@FreeBSD.org> | 2022-03-09 21:22:02 +0000 |
commit | 44eb8cfdc69bb31f11293a8d4f6f36b608887b64 (patch) | |
tree | 50e0ed5fb14f2308f921107985ab7de3cafe3726 | |
parent | f8e07f2f968587e58e20755b4aa5c90a0a09aec3 (diff) | |
download | src-44eb8cfdc69bb31f11293a8d4f6f36b608887b64.tar.gz src-44eb8cfdc69bb31f11293a8d4f6f36b608887b64.zip |
cp: Make -P work without -R as per POSIX
According to POSIX, cp should allow the `-P` flag to work whether `-R`
is specified or not. Currently, the `-P` option only works along with
`-R`.
PR: 199466
(cherry picked from commit 97e13037915c22162f199461f56951793d669f57)
-rw-r--r-- | bin/cp/cp.1 | 16 | ||||
-rw-r--r-- | bin/cp/cp.c | 13 | ||||
-rwxr-xr-x | bin/cp/tests/cp_test.sh | 11 |
3 files changed, 31 insertions, 9 deletions
diff --git a/bin/cp/cp.1 b/bin/cp/cp.1 index f7e2d639def7..f6ff23a16f41 100644 --- a/bin/cp/cp.1 +++ b/bin/cp/cp.1 @@ -32,7 +32,7 @@ .\" @(#)cp.1 8.3 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd June 6, 2015 +.Dd February 23, 2022 .Dt CP 1 .Os .Sh NAME @@ -55,6 +55,14 @@ .Op Fl f | i | n .Op Fl alpsvx .Ar source_file ... target_directory +.Nm +.Op Fl f | i | n +.Op Fl alPpsvx +.Ar source_file target_file +.Nm +.Op Fl f | i | n +.Op Fl alPpsvx +.Ar source_file ... target_directory .Sh DESCRIPTION In the first synopsis form, the .Nm @@ -84,10 +92,10 @@ If the .Fl R option is specified, all symbolic links are followed. .It Fl P -If the +No symbolic links are followed. +This is the default if the .Fl R -option is specified, no symbolic links are followed. -This is the default. +option is specified. .It Fl R If .Ar source_file diff --git a/bin/cp/cp.c b/bin/cp/cp.c index 14007cf1ee66..e846b0ee6dd2 100644 --- a/bin/cp/cp.c +++ b/bin/cp/cp.c @@ -99,21 +99,23 @@ main(int argc, char *argv[]) { struct stat to_stat, tmp_stat; enum op type; - int ch, fts_options, r, have_trailing_slash; + int Pflag, ch, fts_options, r, have_trailing_slash; char *target; fts_options = FTS_NOCHDIR | FTS_PHYSICAL; + Pflag = 0; while ((ch = getopt(argc, argv, "HLPRafilnprsvx")) != -1) switch (ch) { case 'H': Hflag = 1; - Lflag = 0; + Lflag = Pflag = 0; break; case 'L': Lflag = 1; - Hflag = 0; + Hflag = Pflag = 0; break; case 'P': + Pflag = 1; Hflag = Lflag = 0; break; case 'R': @@ -122,6 +124,7 @@ main(int argc, char *argv[]) case 'a': pflag = 1; Rflag = 1; + Pflag = 1; Hflag = Lflag = 0; break; case 'f': @@ -144,7 +147,7 @@ main(int argc, char *argv[]) break; case 'r': rflag = Lflag = 1; - Hflag = 0; + Hflag = Pflag = 0; break; case 's': sflag = 1; @@ -178,7 +181,7 @@ main(int argc, char *argv[]) fts_options &= ~FTS_PHYSICAL; fts_options |= FTS_LOGICAL; } - } else { + } else if (!Pflag) { fts_options &= ~FTS_PHYSICAL; fts_options |= FTS_LOGICAL | FTS_COMFOLLOW; } diff --git a/bin/cp/tests/cp_test.sh b/bin/cp/tests/cp_test.sh index fa2bf82e1478..eb8852a579c5 100755 --- a/bin/cp/tests/cp_test.sh +++ b/bin/cp/tests/cp_test.sh @@ -117,6 +117,16 @@ recursive_link_Lflag_body() '(' ! -L foo-mirror/foo/baz ')' } +atf_test_case standalone_Pflag +standalone_Pflag_body() +{ + echo "foo" > bar + ln -s bar foo + + atf_check cp -P foo baz + atf_check -o inline:'Symbolic Link\n' stat -f %SHT baz +} + atf_init_test_cases() { atf_add_test_case basic @@ -125,4 +135,5 @@ atf_init_test_cases() atf_add_test_case recursive_link_dflt atf_add_test_case recursive_link_Hflag atf_add_test_case recursive_link_Lflag + atf_add_test_case standalone_Pflag } |