[Toybox] [PATCH] cp: fix copying xattrs on directories.
enh
enh at google.com
Tue Feb 19 17:16:27 PST 2019
Tested manually:
mkdir x
setfattr -n user.key -v value x
./toybox cp -r --preserve=a x y
getfattr -d y
I didn't want to be the first to add a test that uses setfattr/getfattr,
but if you say it's okay I'll send another patch with that.
Fixes: #112
---
toys/posix/cp.c | 57 ++++++++++++++++++++++++++++---------------------
1 file changed, 33 insertions(+), 24 deletions(-)
diff --git a/toys/posix/cp.c b/toys/posix/cp.c
index 5e1a0163..5aee8bdd 100644
--- a/toys/posix/cp.c
+++ b/toys/posix/cp.c
@@ -276,30 +276,6 @@ static int cp_node(struct dirtree *try)
err = 0;
}
- // We only copy xattrs for files because there's no flistxattrat()
- if (TT.pflags&(_CP_xattr|_CP_context)) {
- ssize_t listlen = flistxattr(fdin, 0, 0), len;
- char *name, *value, *list;
-
- if (listlen>0) {
- list = xmalloc(listlen);
- flistxattr(fdin, list, listlen);
- list[listlen-1] = 0; // I do not trust this API.
- for (name = list; name-list < listlen; name += strlen(name)+1) {
- if (!(TT.pflags&_CP_xattr) && strncmp(name, "security.", 9))
- continue;
- if ((len = fgetxattr(fdin, name, 0, 0))>0) {
- value = xmalloc(len);
- if (len == fgetxattr(fdin, name, value, len))
- if (fsetxattr(fdout, name, value, len, 0))
- perror_msg("%s setxattr(%s=%s)", catch, name, value);
- free(value);
- }
- }
- free(list);
- }
- }
-
close(fdin);
}
} while (err && (flags & (FLAG_f|FLAG_n)) && !unlinkat(cfd, catch, 0));
@@ -336,6 +312,39 @@ static int cp_node(struct dirtree *try)
else futimens(fdout, times);
}
+ // POSIX extended attributes
+ if (TT.pflags&(_CP_xattr|_CP_context)) {
+ int fdin = openat(tfd, try->name, O_RDONLY);
+
+ if (fdin == -1) {
+ perror_msg("openat %s", try->name);
+ } else {
+ ssize_t listlen = flistxattr(fdin, 0, 0);
+
+ if (listlen>0) {
+ char *list = xmalloc(listlen), *name, *value;
+
+ flistxattr(fdin, list, listlen);
+ list[listlen-1] = 0; // I do not trust this API.
+ for (name = list; name-list < listlen; name += strlen(name)+1) {
+ ssize_t len;
+
+ if (!(TT.pflags&_CP_xattr) && strncmp(name, "security.", 9))
+ continue;
+ if ((len = fgetxattr(fdin, name, 0, 0))>0) {
+ value = xmalloc(len);
+ if (len == fgetxattr(fdin, name, value, len))
+ if (fsetxattr(fdout, name, value, len, 0))
+ perror_msg("%s setxattr(%s=%s)", catch, name, value);
+ free(value);
+ }
+ }
+ free(list);
+ }
+ close(fdin);
+ }
+ }
+
// mode comes last because other syscalls can strip suid bit
if (fdout != AT_FDCWD) {
if (TT.pflags & _CP_mode) fchmod(fdout, try->st.st_mode);
--
2.21.0.rc0.258.g878e2cd30e-goog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-cp-fix-copying-xattrs-on-directories.patch
Type: text/x-patch
Size: 3295 bytes
Desc: not available
URL: <http://lists.landley.net/pipermail/toybox-landley.net/attachments/20190219/29a2a3e4/attachment.bin>
More information about the Toybox
mailing list