aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2021-02-19 11:12:04 -0600
committerRob Landley <rob@landley.net>2021-02-19 11:13:02 -0600
commitc42089fed7adbf3ae1a0fd73b3a7b1e4f10e31db (patch)
treedf4c3c7d08d63fe94a1705bb82cab44ffffab42c
parent9c7085f484dba1e14f47fc05e249c18922b8db5d (diff)
downloadtoybox-c42089fed7adbf3ae1a0fd73b3a7b1e4f10e31db.tar.gz
Fix cp -t with one argument and make --parents work with -t.
-rwxr-xr-xtests/cp.test5
-rw-r--r--toys/posix/cp.c23
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)