aboutsummaryrefslogtreecommitdiffstats
path: root/ports
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2014-04-22 17:04:23 -0500
committerPeter Seebach <peter.seebach@windriver.com>2014-04-22 17:04:23 -0500
commit5392d265efd29e374080dca062ff1d1a834bfbed (patch)
treefedf5a7db8974343ae3848ada4d5da7956f8873f /ports
parent1c0d6d9a3cbb193a1c2f0e4f57a70781e7b69931 (diff)
downloadpseudo-5392d265efd29e374080dca062ff1d1a834bfbed.tar.gz
pseudo-5392d265efd29e374080dca062ff1d1a834bfbed.tar.bz2
pseudo-5392d265efd29e374080dca062ff1d1a834bfbed.zip
xattr support and other path stuff: reduce allocation and copying
The xattr first-pass implementation was allocating a buffer to hold the name and value for a set operation, then pseudo_client was allocating *another* buffer to hold the path and those two values. pseudo_client_op develops more nuanced argument handling, and also uses a static buffer for the extended paths it sometimes needs. So for the typical use case, only occasional operations will need to reallocate/expand the buffer, and we'll be down to copying things into that buffer once per operation, instead of having two alloc/free pairs and two copies. And of course, that wasn't two alloc/free pairs, it was one alloc/free pair and one alloc without a free. Whoops. Signed-off-by: Peter Seebach <peter.seebach@windriver.com>
Diffstat (limited to 'ports')
-rw-r--r--ports/linux/xattr/pseudo_wrappers.c54
1 files changed, 27 insertions, 27 deletions
diff --git a/ports/linux/xattr/pseudo_wrappers.c b/ports/linux/xattr/pseudo_wrappers.c
index c37c245..40699d6 100644
--- a/ports/linux/xattr/pseudo_wrappers.c
+++ b/ports/linux/xattr/pseudo_wrappers.c
@@ -112,7 +112,7 @@ posix_permissions(const acl_header *header, int entries, int *extra, int *mode)
static ssize_t shared_getxattr(const char *path, int fd, const char *name, void *value, size_t size) {
RC_AND_BUF
- pseudo_debug(PDBGF_XATTR, "getxattr(%s/%d, %s)\n",
+ pseudo_debug(PDBGF_XATTR, "getxattr(%s [fd %d], %s)\n",
path ? path : "<no path>", fd, name);
pseudo_msg_t *result = pseudo_client_op(OP_GET_XATTR, 0, fd, -1, path, &buf, name);
if (result->result != RESULT_SUCCEED) {
@@ -135,31 +135,10 @@ static ssize_t shared_getxattr(const char *path, int fd, const char *name, void
static int shared_setxattr(const char *path, int fd, const char *name, const void *value, size_t size, int flags) {
RC_AND_BUF
-
- char *combined;
- size_t nlen = strlen(name);
- size_t combined_len = nlen + size + 1;
- combined = malloc(combined_len + 1);
- memcpy(combined, name, nlen);
- combined[nlen] = '\0';
- memcpy(combined + nlen + 1, value, size);
- combined[combined_len] = '\0';
-
- pseudo_debug(PDBGF_XATTR, "setxattr(%s/%d, %s, %s => %s [%d])\n",
- path ? path : "<no path>", fd, name, (char *) value, combined + nlen + 1, (int) size);
-
pseudo_op_t op;
- switch (flags) {
- case XATTR_CREATE:
- op = OP_CREATE_XATTR;
- break;
- case XATTR_REPLACE:
- op = OP_REPLACE_XATTR;
- break;
- default:
- op = OP_SET_XATTR;
- break;
- }
+
+ pseudo_debug(PDBGF_XATTR, "setxattr(%s [fd %d], %s => '%.*s')\n",
+ path ? path : "<no path>", fd, name, (int) size, (char *) value);
/* this may be a plain chmod */
if (!strcmp(name, "system.posix_acl_access")) {
@@ -170,7 +149,16 @@ static int shared_setxattr(const char *path, int fd, const char *name, const voi
pseudo_debug(PDBGF_XATTR, "posix_acl_access translated to mode %04o. Remaining attribute(s): %d.\n",
mode, extra);
buf.st_mode = mode;
- pseudo_client_op(path ? OP_CHMOD : OP_FCHMOD, 0, fd, -1, path, &buf);
+ /* we want to actually issue a corresponding chmod,
+ * as well, or else the file ends up 0600 on the
+ * host. Using the slightly-less-efficient wrap_chmod
+ * avoids possible misalignment.
+ */
+ if (path) {
+ wrap_chmod(path, mode);
+ } else {
+ wrap_fchmod(fd, mode);
+ }
/* we are sneaky, and do not actually record this using
* extended attributes. */
if (!extra) {
@@ -179,7 +167,19 @@ static int shared_setxattr(const char *path, int fd, const char *name, const voi
}
}
- pseudo_msg_t *result = pseudo_client_op(op, 0, fd, -1, path, &buf, combined, combined_len);
+ switch (flags) {
+ case XATTR_CREATE:
+ op = OP_CREATE_XATTR;
+ break;
+ case XATTR_REPLACE:
+ op = OP_REPLACE_XATTR;
+ break;
+ default:
+ op = OP_SET_XATTR;
+ break;
+ }
+
+ pseudo_msg_t *result = pseudo_client_op(op, 0, fd, -1, path, &buf, name, value, size);
/* we automatically assume success */
if (op == OP_SET_XATTR) {