]> xenbits.xensource.com Git - people/royger/freebsd.git/commitdiff
cp: Make -P work without -R as per POSIX
authorCameron Katri <me@cameronkatri.com>
Wed, 23 Feb 2022 18:55:13 +0000 (12:55 -0600)
committerKyle Evans <kevans@FreeBSD.org>
Wed, 9 Mar 2022 21:22:02 +0000 (15:22 -0600)
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)

bin/cp/cp.1
bin/cp/cp.c
bin/cp/tests/cp_test.sh

index f7e2d639def72fc8a2d9639895b8ef915ad68f47..f6ff23a16f411a8d31294d7e8d9e4d6514285808 100644 (file)
@@ -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
 .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
index 14007cf1ee66e7a292131c79ed75f6e26672dbe6..e846b0ee6dd2a73c7e0f4d7bb59c79511f5c893a 100644 (file)
@@ -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;
        }
index fa2bf82e14789a9999fd71b84f0ad5766956261d..eb8852a579c50c45be183c788151783c62b256da 100755 (executable)
@@ -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
 }