aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/test/cp.test19
-rw-r--r--toys/cp.c15
2 files changed, 27 insertions, 7 deletions
diff --git a/scripts/test/cp.test b/scripts/test/cp.test
index 858a382d..fcbab0e5 100755
--- a/scripts/test/cp.test
+++ b/scripts/test/cp.test
@@ -72,7 +72,24 @@ testing "cp file1 file2 dir" \
rm one two random
rm -rf dir
-# cp -r ../source destdir
+mkdir -p one/two/three/four
+touch one/two/three/five
+touch one/{six,seven,eight}
+testing "cp -r /abspath dest" \
+ "cp -r \"$(readlink -f one)\" dir && diff -r one dir && echo yes" \
+ "yes\n" "" ""
+mkdir dir2
+testing "cp -r dir1/* dir2" \
+ "cp -r one/* dir2 && diff -r one dir2 && echo yes" "yes\n" "" ""
+rm -rf one dir2
+# cp -r ../source destdir
+# cp -r one/two/three missing
+# cp -r one/two/three two
+# mkdir one; touch one/two; ln -s two one/three
# cp file1 file2 dir
# cp file1 missing file2 -> dir
+
+# Make sure it's truncating existing file
+# copy with -d at top level, with -d in directory, without -d at top level,
+# without -d in directory
diff --git a/toys/cp.c b/toys/cp.c
index 0e2d04ed..13cb9672 100644
--- a/toys/cp.c
+++ b/toys/cp.c
@@ -123,7 +123,9 @@ int cp_node(char *path, struct dirtree *node)
// Find appropriate chunk of path for destination.
- for (n = node;;n = n->parent) {
+ n = node;
+ if (!TT.destisdir) n = n->parent;
+ for (;;n = n->parent) {
while (s!=path) {
if (*(--s)=='/') break;
}
@@ -180,13 +182,14 @@ void cp_main(void)
continue;
}
- dst = strrchr(src, '/');
- if (dst) dst++;
- else dst=src;
-
// Copy directory or file.
- if (TT.destisdir) dst = xmsprintf("%s/%s", TT.destname, dst);
+ if (TT.destisdir) {
+ dst = strrchr(src, '/');
+ if (dst) dst++;
+ else dst=src;
+ dst = xmsprintf("%s/%s", TT.destname, dst);
+ } else dst = TT.destname;
if (S_ISDIR(st.st_mode)) {
if (toys.optflags & FLAG_r) {
cp_file(src, dst, &st);