diff options
-rwxr-xr-x | tests/cp.test | 5 | ||||
-rw-r--r-- | toys/posix/cp.c | 23 |
2 files changed, 20 insertions, 8 deletions
diff --git a/tests/cp.test b/tests/cp.test index 293f0348..3fcea3be 100755 --- a/tests/cp.test +++ b/tests/cp.test @@ -131,6 +131,11 @@ testing "-P symlink" "cp -P lnk ldst && stat -c %F ldst" "symbolic link\n" "" "" testing "follow symlink" "cp lnk ldst2 && stat -c %F ldst2" "regular file\n" "" "" rm file fdst lnk ldst ldst2 +mkdir sub +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 + # 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 3fe1908d..56fbadf9 100644 --- a/toys/posix/cp.c +++ b/toys/posix/cp.c @@ -15,8 +15,8 @@ // 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, "<2(preserve):;D(parents)RHLPprdaslvnF(remove-destination)fit:T[-HLPd][-ni]", TOYFLAG_BIN)) -USE_MV(NEWTOY(mv, "<2vnF(remove-destination)fit:T[-ni]", TOYFLAG_BIN)) +USE_CP(NEWTOY(cp, "<1(preserve):;D(parents)RHLPprdaslvnF(remove-destination)fit:T[-HLPd][-ni]", 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)) config CP @@ -364,16 +364,24 @@ void cp_main(void) { char *tt = *toys.which->name == 'i' ? TT.i.t : TT.c.t, *destname = tt ? : toys.optargs[--toys.optc]; - int i, destdir = !stat(destname, &TT.top) && S_ISDIR(TT.top.st_mode); + int i, destdir = !stat(destname, &TT.top); + + if (!toys.optc) error_exit("Needs 2 arguments"); + if (!destdir && errno==ENOENT && FLAG(D)) { + if (tt && mkpathat(AT_FDCWD, tt, 0777, MKPATHAT_MAKE|MKPATHAT_MKLAST)) + perror_exit("-t '%s'", tt); + destdir = 1; + } else { + destdir = destdir && S_ISDIR(TT.top.st_mode); + if (!destdir && (toys.optc>1 || FLAG(D) || tt)) + error_exit("'%s' not directory", destname); + } if (FLAG(T)) { if (toys.optc>1) help_exit("Max 2 arguments"); if (destdir) error_exit("'%s' is a directory", destname); } - if ((toys.optc>1 || FLAG(D) || tt) && !destdir) - error_exit("'%s' not directory", destname); - if (FLAG(a)||FLAG(p)) TT.pflags = _CP_mode|_CP_ownership|_CP_timestamps; // Not using comma_args() (yet?) because interpeting as letters. @@ -511,13 +519,12 @@ void install_main(void) return; } - if (FLAG(D)) { + if (FLAG(D) && !FLAG(t)) { TT.destname = toys.optargs[toys.optc-1]; if (mkpathat(AT_FDCWD, TT.destname, 0, MKPATHAT_MAKE)) perror_exit("-D '%s'", TT.destname); if (toys.optc == 1) return; } - if (toys.optc < 2) error_exit("needs 2 args"); // Translate flags from install to cp toys.optflags = cp_flag_F() + cp_flag_v()*!!FLAG(v) |