aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtests/cp.test7
-rw-r--r--toys/posix/cp.c2
2 files changed, 9 insertions, 0 deletions
diff --git a/tests/cp.test b/tests/cp.test
index 2b89e2f2..a720d1f5 100755
--- a/tests/cp.test
+++ b/tests/cp.test
@@ -89,6 +89,13 @@ testing "-r dir1/* dir2" \
"cp -r one/* dir2 && diff -r one dir2 && echo yes" "yes\n" "" ""
rm -rf one dir dir2
+touch walrus
+chmod 644 walrus
+ln -s walrus woot
+
+testing "symlink dest permissions" "cp woot carpenter && stat -c %A carpenter" \
+ "-rw-r--r--\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 da658319..5e1a0163 100644
--- a/toys/posix/cp.c
+++ b/toys/posix/cp.c
@@ -268,6 +268,8 @@ static int cp_node(struct dirtree *try)
catch = try->name;
break;
}
+ // When copying contents use symlink target's attributes
+ if (S_ISLNK(try->st.st_mode)) fstat(fdin, &try->st);
fdout = openat(cfd, catch, O_RDWR|O_CREAT|O_TRUNC, try->st.st_mode);
if (fdout >= 0) {
xsendfile(fdin, fdout);