From 2a6f03eb088b21a68ee4f5fa45b7cd4f7c7bc558 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Wed, 7 Apr 2021 07:00:13 -0500 Subject: Add cp -u --- tests/cp.test | 5 +++++ toys/posix/cp.c | 7 +++++-- 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)); -- cgit v1.2.3