aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2021-04-07 07:00:13 -0500
committerRob Landley <rob@landley.net>2021-04-07 07:00:13 -0500
commit2a6f03eb088b21a68ee4f5fa45b7cd4f7c7bc558 (patch)
tree6e8f0e5249844efc8a9b7ac702ddaea9402be559
parentcecc41a3c52519ac1d65989b266fec32a2bd6ff7 (diff)
downloadtoybox-2a6f03eb088b21a68ee4f5fa45b7cd4f7c7bc558.tar.gz
Add cp -u
-rwxr-xr-xtests/cp.test5
-rw-r--r--toys/posix/cp.c7
2 files changed, 10 insertions, 2 deletions
diff --git a/tests/cp.test b/tests/cp.test
index 3fcea3be..b0d5d3a4 100755
--- a/tests/cp.test
+++ b/tests/cp.test
@@ -136,6 +136,11 @@ testing "-t one arg" 'cp -t sub/ input && cat sub/input' 'yes\n' 'yes\n' ''
toyonly testing "-Dt" 'cp -Dt sub2 input && cat sub2/input' 'and\n' 'and\n' ''
rm -rf sub sub2
+testing '-u1' 'echo one>one; sleep .1; echo two>two; cp -u one two; cat two' \
+ 'two\n' '' ''
+testing '-u2' 'echo two>two; sleep .1; echo one>one; cp -u one two; cat two' \
+ 'one\n' '' ''
+
# cp -r ../source destdir
# cp -r one/two/three missing
# cp -r one/two/three two
diff --git a/toys/posix/cp.c b/toys/posix/cp.c
index a27c200a..8eaecc9c 100644
--- a/toys/posix/cp.c
+++ b/toys/posix/cp.c
@@ -15,7 +15,7 @@
// options shared between mv/cp must be in same order (right to left)
// for FLAG macros to work out right in shared infrastructure.
-USE_CP(NEWTOY(cp, "<1(preserve):;D(parents)RHLPprdaslvnF(remove-destination)fit:T[-HLPd][-ni]", TOYFLAG_BIN))
+USE_CP(NEWTOY(cp, "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu]", TOYFLAG_BIN))
USE_MV(NEWTOY(mv, "<1vnF(remove-destination)fit:T[-ni]", TOYFLAG_BIN))
USE_INSTALL(NEWTOY(install, "<1cdDpsvt:m:o:g:", TOYFLAG_USR|TOYFLAG_BIN))
@@ -38,6 +38,7 @@ config CP
-L Follow all symlinks
-l Hard link instead of copy
-n No clobber (don't overwrite DEST)
+ -u Update (keep newest mtime)
-P Do not follow symlinks
-p Preserve timestamps, ownership, and mode
-R Recurse into subdirectories (DEST must be a directory)
@@ -152,7 +153,7 @@ static int cp_node(struct dirtree *try)
return 0;
}
- // Handle -invF
+ // Handle -inuvF
if (!faccessat(cfd, catch, F_OK, 0) && !S_ISDIR(cst.st_mode)) {
char *s;
@@ -165,6 +166,8 @@ static int cp_node(struct dirtree *try)
error_msg("unlink '%s'", catch);
return 0;
} else if (flags & FLAG_n) return 0;
+ else if ((flags & FLAG_u) && nanodiff(&try->st.st_mtim, &cst.st_mtim)>0)
+ return 0;
else if (flags & FLAG_i) {
fprintf(stderr, "%s: overwrite '%s'", toys.which->name,
s = dirtree_path(try, 0));