Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F131938478
D51100.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D51100.diff
View Options
diff --git a/bin/cp/cp.1 b/bin/cp/cp.1
--- a/bin/cp/cp.1
+++ b/bin/cp/cp.1
@@ -29,7 +29,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd March 28, 2024
+.Dd July 1, 2025
.Dt CP 1
.Os
.Sh NAME
@@ -84,16 +84,16 @@
.Fl R
option is specified, symbolic links on the command line are followed.
(Symbolic links encountered in the tree traversal are not followed.)
-.It Fl L
+.It Fl L , Fl -dereference
If the
.Fl R
option is specified, all symbolic links are followed.
-.It Fl P
+.It Fl P , Fl -no-dereference
No symbolic links are followed.
This is the default if the
.Fl R
option is specified.
-.It Fl R
+.It Fl R , Fl -recursive
If
.Ar source_file
designates a directory,
@@ -121,11 +121,11 @@
or
.Xr pax 1
instead.
-.It Fl a
+.It Fl a , Fl -archive
Archive mode.
Same as
.Fl RpP .
-.It Fl f
+.It Fl f , Fl -force
For each existing destination pathname, remove it and
create a new file, without prompting for confirmation
regardless of its permissions.
@@ -136,10 +136,8 @@
or
.Fl n
options.)
-.It Fl i
-Cause
-.Nm
-to write a prompt to the standard error output before copying a file
+.It Fl i , Fl -interactive
+Write a prompt to the standard error output before copying a file
that would overwrite an existing file.
If the response from the standard input begins with the character
.Sq Li y
@@ -153,13 +151,13 @@
or
.Fl n
options.)
-.It Fl l
+.It Fl l , Fl -link
Create hard links to regular files in a hierarchy instead of copying.
.It Fl N
When used with
.Fl p ,
suppress copying file flags.
-.It Fl n
+.It Fl n , Fl -no-clobber
Do not overwrite an existing file.
(The
.Fl n
@@ -169,9 +167,7 @@
.Fl i
options.)
.It Fl p
-Cause
-.Nm
-to preserve the following attributes of each source
+Preserve the following attributes of each source
file in the copy: modification time, access time,
file flags, file mode, ACL, user ID, and group ID, as allowed by permissions.
.Pp
@@ -188,14 +184,25 @@
and either the user ID or group ID cannot be preserved, neither
the set-user-ID nor set-group-ID bits are preserved in the copy's
permissions.
-.It Fl s
-Create symbolic links to regular files in a hierarchy instead of copying.
-.It Fl v
-Cause
+.It Fl -sort
+Visit and traverse sources in (non-localized) lexicographical order.
+Normally,
.Nm
-to be verbose, showing files as they are copied.
-.It Fl x
-File system mount points are not traversed.
+visits the sources in the order they were listed on the command line,
+and if recursing, traverses their contents in whichever order they
+were returned in by the kernel, which may be the order in which they
+were created, lexicographical order, or something else entirely.
+With
+.Fl -sort ,
+the sources are both visited and traversed in lexicographical order.
+This is mostly useful for testing.
+.It Fl s , Fl -symbolic-link
+Create symbolic links to regular files in a hierarchy instead of copying.
+.It Fl v , Fl -verbose
+Be verbose, showing both the source and destination path of each file
+as is copied.
+.It Fl x , Fl -one-file-system
+Do not traverse file system mount points.
.El
.Pp
For each destination file that already exists, its contents are
diff --git a/bin/cp/cp.c b/bin/cp/cp.c
--- a/bin/cp/cp.c
+++ b/bin/cp/cp.c
@@ -55,6 +55,7 @@
#include <errno.h>
#include <fcntl.h>
#include <fts.h>
+#include <getopt.h>
#include <limits.h>
#include <signal.h>
#include <stdbool.h>
@@ -69,8 +70,8 @@
#define END(buf) (buf + sizeof(buf))
PATH_T to = { .dir = -1, .end = to.path };
-int Nflag, fflag, iflag, lflag, nflag, pflag, sflag, vflag;
-static int Hflag, Lflag, Pflag, Rflag, rflag;
+bool Nflag, fflag, iflag, lflag, nflag, pflag, sflag, vflag;
+static bool Hflag, Lflag, Pflag, Rflag, rflag, Sflag;
volatile sig_atomic_t info;
enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
@@ -78,6 +79,27 @@
static int copy(char *[], enum op, int, struct stat *);
static void siginfo(int __unused);
+enum {
+ SORT_OPT = CHAR_MAX,
+};
+
+static const struct option long_opts[] =
+{
+ { "archive", no_argument, NULL, 'a' },
+ { "force", no_argument, NULL, 'f' },
+ { "interactive", no_argument, NULL, 'i' },
+ { "dereference", no_argument, NULL, 'L' },
+ { "link", no_argument, NULL, 'l' },
+ { "no-clobber", no_argument, NULL, 'n' },
+ { "no-dereference", no_argument, NULL, 'P' },
+ { "recursive", no_argument, NULL, 'R' },
+ { "symbolic-link", no_argument, NULL, 's' },
+ { "verbose", no_argument, NULL, 'v' },
+ { "one-file-system", no_argument, NULL, 'x' },
+ { "sort", no_argument, NULL, SORT_OPT },
+ { 0 }
+};
+
int
main(int argc, char *argv[])
{
@@ -88,63 +110,67 @@
bool have_trailing_slash = false;
fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
- while ((ch = getopt(argc, argv, "HLPRafilNnprsvx")) != -1)
+ while ((ch = getopt_long(argc, argv, "HLPRafilNnprsvx", long_opts,
+ NULL)) != -1)
switch (ch) {
case 'H':
- Hflag = 1;
- Lflag = Pflag = 0;
+ Hflag = true;
+ Lflag = Pflag = false;
break;
case 'L':
- Lflag = 1;
- Hflag = Pflag = 0;
+ Lflag = true;
+ Hflag = Pflag = false;
break;
case 'P':
- Pflag = 1;
- Hflag = Lflag = 0;
+ Pflag = true;
+ Hflag = Lflag = false;
break;
case 'R':
- Rflag = 1;
+ Rflag = true;
break;
case 'a':
- pflag = 1;
- Rflag = 1;
- Pflag = 1;
- Hflag = Lflag = 0;
+ pflag = true;
+ Rflag = true;
+ Pflag = true;
+ Hflag = Lflag = false;
break;
case 'f':
- fflag = 1;
- iflag = nflag = 0;
+ fflag = true;
+ iflag = nflag = false;
break;
case 'i':
- iflag = 1;
- fflag = nflag = 0;
+ iflag = true;
+ fflag = nflag = false;
break;
case 'l':
- lflag = 1;
+ lflag = true;
break;
case 'N':
- Nflag = 1;
+ Nflag = true;
break;
case 'n':
- nflag = 1;
- fflag = iflag = 0;
+ nflag = true;
+ fflag = iflag = false;
break;
case 'p':
- pflag = 1;
+ pflag = true;
break;
case 'r':
- rflag = Lflag = 1;
- Hflag = Pflag = 0;
+ rflag = Lflag = true;
+ Hflag = Pflag = false;
break;
case 's':
- sflag = 1;
+ sflag = true;
break;
case 'v':
- vflag = 1;
+ vflag = true;
break;
case 'x':
fts_options |= FTS_XDEV;
break;
+ case SORT_OPT:
+ Sflag = true;
+ break;
default:
usage();
}
@@ -159,7 +185,7 @@
if (lflag && sflag)
errx(1, "the -l and -s options may not be specified together");
if (rflag)
- Rflag = 1;
+ Rflag = true;
if (Rflag) {
if (Hflag)
fts_options |= FTS_COMFOLLOW;
@@ -262,6 +288,12 @@
&to_stat)));
}
+static int
+ftscmp(const FTSENT * const *a, const FTSENT * const *b)
+{
+ return (strcmp((*a)->fts_name, (*b)->fts_name));
+}
+
static int
copy(char *argv[], enum op type, int fts_options, struct stat *root_stat)
{
@@ -305,7 +337,7 @@
}
level = FTS_ROOTLEVEL;
- if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
+ if ((ftsp = fts_open(argv, fts_options, Sflag ? ftscmp : NULL)) == NULL)
err(1, "fts_open");
for (badcp = rval = 0;
(curr = fts_read(ftsp)) != NULL;
diff --git a/bin/cp/extern.h b/bin/cp/extern.h
--- a/bin/cp/extern.h
+++ b/bin/cp/extern.h
@@ -37,7 +37,7 @@
} PATH_T;
extern PATH_T to;
-extern int Nflag, fflag, iflag, lflag, nflag, pflag, sflag, vflag;
+extern bool Nflag, fflag, iflag, lflag, nflag, pflag, sflag, vflag;
extern volatile sig_atomic_t info;
__BEGIN_DECLS
diff --git a/bin/cp/tests/cp_test.sh b/bin/cp/tests/cp_test.sh
--- a/bin/cp/tests/cp_test.sh
+++ b/bin/cp/tests/cp_test.sh
@@ -649,7 +649,7 @@
atf_check \
-s exit:1 \
-e match:"^cp: src/b: Permission denied" \
- cp -R src dst
+ cp -R --sort src dst
atf_check test -d dst/a
atf_check cmp src/a/f dst/a/f
atf_check test -d dst/b
@@ -669,7 +669,7 @@
atf_check \
-s exit:1 \
-e match:"^cp: src/b: Permission denied" \
- cp -R src dst
+ cp -R --sort src dst
atf_check test -d dst
atf_check cmp src/a dst/a
atf_check test ! -e dst/b
diff --git a/bin/cp/utils.c b/bin/cp/utils.c
--- a/bin/cp/utils.c
+++ b/bin/cp/utils.c
@@ -105,7 +105,7 @@
ssize_t wcount;
off_t wtotal;
int ch, checkch, from_fd, rval, to_fd;
- int use_copy_file_range = 1;
+ bool use_copy_file_range = true;
fs = entp->fts_statp;
from_fd = to_fd = -1;
@@ -210,7 +210,7 @@
to_fd, NULL, SSIZE_MAX, 0);
if (wcount < 0 && errno == EINVAL) {
/* probably a non-seekable descriptor */
- use_copy_file_range = 0;
+ use_copy_file_range = false;
}
}
if (!use_copy_file_range) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Oct 13, 8:43 AM (18 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23667466
Default Alt Text
D51100.diff (8 KB)
Attached To
Mode
D51100: cp: Add an option to visit sources in order.
Attached
Detach File
Event Timeline
Log In to Comment