diff options
Diffstat (limited to 'ports/linux')
30 files changed, 293 insertions, 14 deletions
diff --git a/ports/linux/guts/fgetxattr.c b/ports/linux/noxattr/guts/fgetxattr.c index 9d33643..9d33643 100644 --- a/ports/linux/guts/fgetxattr.c +++ b/ports/linux/noxattr/guts/fgetxattr.c diff --git a/ports/linux/guts/flistxattr.c b/ports/linux/noxattr/guts/flistxattr.c index 77db021..77db021 100644 --- a/ports/linux/guts/flistxattr.c +++ b/ports/linux/noxattr/guts/flistxattr.c diff --git a/ports/linux/guts/fremovexattr.c b/ports/linux/noxattr/guts/fremovexattr.c index 529a9de..529a9de 100644 --- a/ports/linux/guts/fremovexattr.c +++ b/ports/linux/noxattr/guts/fremovexattr.c diff --git a/ports/linux/guts/fsetxattr.c b/ports/linux/noxattr/guts/fsetxattr.c index 3c56ddd..3c56ddd 100644 --- a/ports/linux/guts/fsetxattr.c +++ b/ports/linux/noxattr/guts/fsetxattr.c diff --git a/ports/linux/guts/getxattr.c b/ports/linux/noxattr/guts/getxattr.c index fe8912d..fe8912d 100644 --- a/ports/linux/guts/getxattr.c +++ b/ports/linux/noxattr/guts/getxattr.c diff --git a/ports/linux/guts/lgetxattr.c b/ports/linux/noxattr/guts/lgetxattr.c index 404211f..404211f 100644 --- a/ports/linux/guts/lgetxattr.c +++ b/ports/linux/noxattr/guts/lgetxattr.c diff --git a/ports/linux/guts/listxattr.c b/ports/linux/noxattr/guts/listxattr.c index 1b0b5e7..1b0b5e7 100644 --- a/ports/linux/guts/listxattr.c +++ b/ports/linux/noxattr/guts/listxattr.c diff --git a/ports/linux/guts/llistxattr.c b/ports/linux/noxattr/guts/llistxattr.c index a33f970..a33f970 100644 --- a/ports/linux/guts/llistxattr.c +++ b/ports/linux/noxattr/guts/llistxattr.c diff --git a/ports/linux/guts/lremovexattr.c b/ports/linux/noxattr/guts/lremovexattr.c index 38429da..38429da 100644 --- a/ports/linux/guts/lremovexattr.c +++ b/ports/linux/noxattr/guts/lremovexattr.c diff --git a/ports/linux/guts/lsetxattr.c b/ports/linux/noxattr/guts/lsetxattr.c index 140ae8d..140ae8d 100644 --- a/ports/linux/guts/lsetxattr.c +++ b/ports/linux/noxattr/guts/lsetxattr.c diff --git a/ports/linux/guts/removexattr.c b/ports/linux/noxattr/guts/removexattr.c index cd7f486..cd7f486 100644 --- a/ports/linux/guts/removexattr.c +++ b/ports/linux/noxattr/guts/removexattr.c diff --git a/ports/linux/guts/setxattr.c b/ports/linux/noxattr/guts/setxattr.c index de2de98..de2de98 100644 --- a/ports/linux/guts/setxattr.c +++ b/ports/linux/noxattr/guts/setxattr.c diff --git a/ports/linux/noxattr/wrapfuncs.in b/ports/linux/noxattr/wrapfuncs.in new file mode 100644 index 0000000..de22ae1 --- /dev/null +++ b/ports/linux/noxattr/wrapfuncs.in @@ -0,0 +1,14 @@ +# we use "pathname" to avoid canonicalizing paths, because these functions are +# unimplemented +ssize_t getxattr(const char *pathname, const char *name, void *value, size_t size); +ssize_t lgetxattr(const char *pathname, const char *name, void *value, size_t size); +ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size); +ssize_t listxattr(const char *pathname, char *list, size_t size); +ssize_t llistxattr(const char *pathname, char *list, size_t size); +ssize_t flistxattr(int filedes, char *list, size_t size); +int setxattr(const char *pathname, const char *name, const void *value, size_t size, int flags); +int lsetxattr(const char *pathname, const char *name, const void *value, size_t size, int flags); +int fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags); +int removexattr(const char *pathname, const char *name); +int lremovexattr(const char *pathname, const char *name); +int fremovexattr(int filedes, const char *name); diff --git a/ports/linux/subports b/ports/linux/subports index 02a4688..b68c25b 100755 --- a/ports/linux/subports +++ b/ports/linux/subports @@ -25,3 +25,8 @@ rm -f dummy.c dummy.o if ! $found; then echo >&2 "Can't tell, omitting clone(2) support." fi +if getfattr --help >/dev/null 2>&1; then + echo "linux/xattr" +else + echo "linux/noxattr" +fi diff --git a/ports/linux/wrapfuncs.in b/ports/linux/wrapfuncs.in index 1ffdb3a..e2b661b 100644 --- a/ports/linux/wrapfuncs.in +++ b/ports/linux/wrapfuncs.in @@ -13,20 +13,6 @@ int fcntl(int fd, int cmd, ...{struct flock *lock}); # just so we know the inums of symlinks char *canonicalize_file_name(const char *filename); int eaccess(const char *path, int mode); -# we use "pathname" to avoid canonicalizing paths, because these functions are -# unimplemented -ssize_t getxattr(const char *pathname, const char *name, void *value, size_t size); -ssize_t lgetxattr(const char *pathname, const char *name, void *value, size_t size); -ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size); -ssize_t listxattr(const char *pathname, char *list, size_t size); -ssize_t llistxattr(const char *pathname, char *list, size_t size); -ssize_t flistxattr(int filedes, char *list, size_t size); -int setxattr(const char *pathname, const char *name, const void *value, size_t size, int flags); -int lsetxattr(const char *pathname, const char *name, const void *value, size_t size, int flags); -int fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags); -int removexattr(const char *pathname, const char *name); -int lremovexattr(const char *pathname, const char *name); -int fremovexattr(int filedes, const char *name); int open64(const char *path, int flags, ...{mode_t mode}); /* flags=0 */ int openat64(int dirfd, const char *path, int flags, ...{mode_t mode}); /* flags=0 */ int __openat64_2(int dirfd, const char *path, int flags); /* flags=0 */ diff --git a/ports/linux/xattr/guts/fgetxattr.c b/ports/linux/xattr/guts/fgetxattr.c new file mode 100644 index 0000000..ae8c3a3 --- /dev/null +++ b/ports/linux/xattr/guts/fgetxattr.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size) + * ssize_t rc = -1; + */ + rc = shared_getxattr(NULL, filedes, name, value, size); + +/* return rc; + * } + */ diff --git a/ports/linux/xattr/guts/flistxattr.c b/ports/linux/xattr/guts/flistxattr.c new file mode 100644 index 0000000..cdd9454 --- /dev/null +++ b/ports/linux/xattr/guts/flistxattr.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t flistxattr(int filedes, char *list, size_t size) + * ssize_t rc = -1; + */ + rc = shared_listxattr(NULL, filedes, list, size); + +/* return rc; + * } + */ diff --git a/ports/linux/xattr/guts/fremovexattr.c b/ports/linux/xattr/guts/fremovexattr.c new file mode 100644 index 0000000..a029d2c --- /dev/null +++ b/ports/linux/xattr/guts/fremovexattr.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int fremovexattr(int filedes, const char *name) + * int rc = -1; + */ + rc = shared_removexattr(NULL, filedes, name); + +/* return rc; + * } + */ diff --git a/ports/linux/xattr/guts/fsetxattr.c b/ports/linux/xattr/guts/fsetxattr.c new file mode 100644 index 0000000..cbed2ea --- /dev/null +++ b/ports/linux/xattr/guts/fsetxattr.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags) + * int rc = -1; + */ + rc = shared_setxattr(NULL, filedes, name, value, size, flags); + +/* return rc; + * } + */ diff --git a/ports/linux/xattr/guts/getxattr.c b/ports/linux/xattr/guts/getxattr.c new file mode 100644 index 0000000..7bd2bf5 --- /dev/null +++ b/ports/linux/xattr/guts/getxattr.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t getxattr(const char *path, const char *name, void *value, size_t size) + * ssize_t rc = -1; + */ + rc = shared_getxattr(path, -1, name, value, size); + +/* return rc; + * } + */ diff --git a/ports/linux/xattr/guts/lgetxattr.c b/ports/linux/xattr/guts/lgetxattr.c new file mode 100644 index 0000000..675d3da --- /dev/null +++ b/ports/linux/xattr/guts/lgetxattr.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size) + * ssize_t rc = -1; + */ + rc = shared_getxattr(path, -1, name, value, size); + +/* return rc; + * } + */ diff --git a/ports/linux/xattr/guts/listxattr.c b/ports/linux/xattr/guts/listxattr.c new file mode 100644 index 0000000..0decf71 --- /dev/null +++ b/ports/linux/xattr/guts/listxattr.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t listxattr(const char *path, char *list, size_t size) + * ssize_t rc = -1; + */ + rc = shared_listxattr(path, -1, list, size); + +/* return rc; + * } + */ diff --git a/ports/linux/xattr/guts/llistxattr.c b/ports/linux/xattr/guts/llistxattr.c new file mode 100644 index 0000000..9934256 --- /dev/null +++ b/ports/linux/xattr/guts/llistxattr.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t llistxattr(const char *path, char *list, size_t size) + * ssize_t rc = -1; + */ + rc = shared_listxattr(path, -1, list, size); + +/* return rc; + * } + */ diff --git a/ports/linux/xattr/guts/lremovexattr.c b/ports/linux/xattr/guts/lremovexattr.c new file mode 100644 index 0000000..1f39788 --- /dev/null +++ b/ports/linux/xattr/guts/lremovexattr.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int lremovexattr(const char *path, const char *name) + * int rc = -1; + */ + rc = shared_removexattr(path, -1, name); + +/* return rc; + * } + */ diff --git a/ports/linux/xattr/guts/lsetxattr.c b/ports/linux/xattr/guts/lsetxattr.c new file mode 100644 index 0000000..b167b15 --- /dev/null +++ b/ports/linux/xattr/guts/lsetxattr.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int lsetxattr(const char *path, const char *name, const void *value, size_t size, int flags) + * int rc = -1; + */ + rc = shared_setxattr(path, -1, name, value, size, flags); + +/* return rc; + * } + */ diff --git a/ports/linux/xattr/guts/removexattr.c b/ports/linux/xattr/guts/removexattr.c new file mode 100644 index 0000000..0d4d8e3 --- /dev/null +++ b/ports/linux/xattr/guts/removexattr.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int removexattr(const char *path, const char *name) + * int rc = -1; + */ + rc = shared_removexattr(path, -1, name); + +/* return rc; + * } + */ diff --git a/ports/linux/xattr/guts/setxattr.c b/ports/linux/xattr/guts/setxattr.c new file mode 100644 index 0000000..dd85252 --- /dev/null +++ b/ports/linux/xattr/guts/setxattr.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int setxattr(const char *path, const char *name, const void *value, size_t size, int flags) + * int rc = -1; + */ + rc = shared_setxattr(path, -1, name, value, size, flags); + +/* return rc; + * } + */ diff --git a/ports/linux/xattr/portdefs.h b/ports/linux/xattr/portdefs.h new file mode 100644 index 0000000..ec030b7 --- /dev/null +++ b/ports/linux/xattr/portdefs.h @@ -0,0 +1 @@ +#include <attr/xattr.h> diff --git a/ports/linux/xattr/pseudo_wrappers.c b/ports/linux/xattr/pseudo_wrappers.c new file mode 100644 index 0000000..7fe44a6 --- /dev/null +++ b/ports/linux/xattr/pseudo_wrappers.c @@ -0,0 +1,117 @@ +/* shared functionality for the xattr code */ +/* Each of these functions is expecting to get an optional name, and + * a populated statbuf to use for sending messages to the server. + */ + +#define RC_AND_BUF \ + int rc; \ + PSEUDO_STATBUF buf; \ + if (path) { \ + rc = base_lstat(path, &buf); \ + } else { \ + rc = base_fstat(fd, &buf); \ + } \ + if (rc == -1) { \ + return rc; \ + } + +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", + 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) { + errno = ENOATTR; + return -1; + } + + if (value) { + pseudo_debug(PDBGF_XATTR, "returned attributes: '%s' (%d bytes)\n", + result->path, result->pathlen); + if (size >= result->pathlen) { + memcpy(value, result->path, result->pathlen); + } else { + memcpy(value, result->path, size); + errno = ERANGE; + } + } + return result->pathlen; +} + +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_msg_t *result = pseudo_client_op(op, 0, fd, -1, path, &buf, combined, combined_len); + + /* we automatically assume success */ + if (op == OP_SET_XATTR) { + return 0; + } + + /* CREATE/REPLACE operations can report failure */ + if (!result || result->result == RESULT_FAIL) { + return -1; + } + + return 0; +} + +static ssize_t shared_listxattr(const char *path, int fd, char *list, size_t size) { + RC_AND_BUF + pseudo_msg_t *result = pseudo_client_op(OP_LIST_XATTR, 0, fd, -1, path, &buf); + if (result->result != RESULT_SUCCEED) { + pseudo_debug(PDBGF_XATTR, "listxattr: no success.\n"); + errno = ENOATTR; + return -1; + } + if (list) { + pseudo_debug(PDBGF_XATTR, "listxattr: %d bytes of names, starting '%.*s'\n", + (int) result->pathlen, (int) result->pathlen, result->path); + if (size >= result->pathlen) { + memcpy(list, result->path, result->pathlen); + } else { + memcpy(list, result->path, size); + errno = ERANGE; + } + } + return result->pathlen; +} + +static int shared_removexattr(const char *path, int fd, const char *name) { + RC_AND_BUF + pseudo_msg_t *result = pseudo_client_op(OP_REMOVE_XATTR, 0, fd, -1, path, &buf, name); + + if (result->result != RESULT_SUCCEED) { + /* docs say ENOATTR, but I don't have one */ + errno = ENOENT; + return -1; + } + return 0; +} + diff --git a/ports/linux/xattr/wrapfuncs.in b/ports/linux/xattr/wrapfuncs.in new file mode 100644 index 0000000..edfc788 --- /dev/null +++ b/ports/linux/xattr/wrapfuncs.in @@ -0,0 +1,12 @@ +ssize_t getxattr(const char *path, const char *name, void *value, size_t size) /* flags=0 */; +ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size) /* flags=AT_SYMLINK_NOFOLLOW */; +ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size); +int setxattr(const char *path, const char *name, const void *value, size_t size, int flags) /* flags=0 */; +int lsetxattr(const char *path, const char *name, const void *value, size_t size, int flags) /* flags=AT_SYMLINK_NOFOLLOW */; +int fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags); +ssize_t listxattr(const char *path, char *list, size_t size) /* flags=0 */; +ssize_t llistxattr(const char *path, char *list, size_t size) /* flags=AT_SYMLINK_NOFOLLOW */; +ssize_t flistxattr(int filedes, char *list, size_t size); +int removexattr(const char *path, const char *name) /* flags=0 */; +int lremovexattr(const char *path, const char *name) /* flags=AT_SYMLINK_NOFOLLOW */; +int fremovexattr(int filedes, const char *name); |