Add the first part of extended attribute support: extattrctl, extattr_set_file, extattr_get_file, extattr_delete_file, extattr_set_fd, extattr_get_fd, and extattr_delete_fd.
Signed-off-by: Stacey Son <[email protected]> Signed-off-by: Warner Losh <[email protected]> Assisted-by: Claude Opus 4.6 (1M context) --- bsd-user/freebsd/os-extattr.h | 208 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) diff --git a/bsd-user/freebsd/os-extattr.h b/bsd-user/freebsd/os-extattr.h new file mode 100644 index 0000000000..f1dfa344cf --- /dev/null +++ b/bsd-user/freebsd/os-extattr.h @@ -0,0 +1,208 @@ +/* + * FreeBSD extended attributes and ACL system call support + * + * Copyright (c) 2013 Stacey D. Son + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include <sys/extattr.h> +#include <sys/acl.h> + +/* extattrctl() */ +static inline abi_long do_freebsd_extattrctl(abi_ulong arg1, abi_ulong arg2, + abi_ulong arg3, abi_ulong arg4, + abi_ulong arg5) +{ + abi_long ret; + void *p, *a, *f; + + p = lock_user_string(arg1); + if (p == NULL) { + return -TARGET_EFAULT; + } + f = lock_user_string(arg3); + if (f == NULL) { + unlock_user(p, arg1, 0); + return -TARGET_EFAULT; + } + a = lock_user_string(arg5); + if (a == NULL) { + unlock_user(f, arg3, 0); + unlock_user(p, arg1, 0); + return -TARGET_EFAULT; + } + ret = get_errno(extattrctl(path(p), arg2, f, arg4, a)); + unlock_user(a, arg5, 0); + unlock_user(f, arg3, 0); + unlock_user(p, arg1, 0); + + return ret; +} + +/* extattr_set_file(2) */ +static inline abi_long do_freebsd_extattr_set_file(abi_ulong arg1, + abi_long arg2, + abi_ulong arg3, + abi_ulong arg4, + abi_ulong arg5) +{ + abi_long ret; + void *p, *a, *d; + + p = lock_user_string(arg1); + if (p == NULL) { + return -TARGET_EFAULT; + } + a = lock_user_string(arg3); + if (a == NULL) { + unlock_user(p, arg1, 0); + return -TARGET_EFAULT; + } + d = lock_user(VERIFY_READ, arg4, arg5, 1); + if (d == NULL) { + unlock_user(a, arg3, 0); + unlock_user(p, arg1, 0); + return -TARGET_EFAULT; + } + ret = get_errno(extattr_set_file(path(p), arg2, a, d, arg5)); + unlock_user(d, arg4, arg5); + unlock_user(a, arg3, 0); + unlock_user(p, arg1, 0); + + return ret; +} + +/* extattr_get_file(2) */ +static inline abi_long do_freebsd_extattr_get_file(abi_ulong arg1, + abi_long arg2, + abi_ulong arg3, + abi_ulong arg4, + abi_ulong arg5) +{ + abi_long ret; + void *p, *a, *d; + + p = lock_user_string(arg1); + if (p == NULL) { + return -TARGET_EFAULT; + } + a = lock_user_string(arg3); + if (a == NULL) { + unlock_user(p, arg1, 0); + return -TARGET_EFAULT; + } + if (arg4 && arg5 > 0) { + d = lock_user(VERIFY_WRITE, arg4, arg5, 0); + if (d == NULL) { + unlock_user(a, arg3, 0); + unlock_user(p, arg1, 0); + return -TARGET_EFAULT; + } + ret = get_errno(extattr_get_file(path(p), arg2, a, d, arg5)); + unlock_user(d, arg4, arg5); + } else { + ret = get_errno(extattr_get_file(path(p), arg2, a, NULL, arg5)); + } + unlock_user(a, arg3, 0); + unlock_user(p, arg1, 0); + + return ret; +} + +/* extattr_delete_file(2) */ +static inline abi_long do_freebsd_extattr_delete_file(abi_ulong arg1, + abi_long arg2, + abi_ulong arg3) +{ + abi_long ret; + void *p, *a; + + p = lock_user_string(arg1); + if (p == NULL) { + return -TARGET_EFAULT; + } + a = lock_user_string(arg3); + if (a == NULL) { + unlock_user(p, arg1, 0); + return -TARGET_EFAULT; + } + ret = get_errno(extattr_delete_file(path(p), arg2, a)); + unlock_user(a, arg3, 0); + unlock_user(p, arg1, 0); + + return ret; +} + +/* extattr_set_fd(2) */ +static inline abi_long do_freebsd_extattr_set_fd(abi_long arg1, abi_long arg2, + abi_ulong arg3, abi_ulong arg4, + abi_ulong arg5) +{ + abi_long ret; + void *a, *d; + + a = lock_user_string(arg3); + if (a == NULL) { + return -TARGET_EFAULT; + } + d = lock_user(VERIFY_READ, arg4, arg5, 1); + if (d == NULL) { + unlock_user(a, arg3, 0); + return -TARGET_EFAULT; + } + ret = get_errno(extattr_set_fd(arg1, arg2, a, d, arg5)); + unlock_user(d, arg4, arg5); + unlock_user(a, arg3, 0); + + return ret; +} + +/* extattr_get_fd(2) */ +static inline abi_long do_freebsd_extattr_get_fd(abi_long arg1, abi_long arg2, + abi_ulong arg3, abi_ulong arg4, + abi_ulong arg5) +{ + abi_long ret; + void *a, *d; + + a = lock_user_string(arg3); + if (a == NULL) { + return -TARGET_EFAULT; + } + + if (arg4 && arg5 > 0) { + d = lock_user(VERIFY_WRITE, arg4, arg5, 0); + if (d == NULL) { + unlock_user(a, arg3, 0); + return -TARGET_EFAULT; + } + ret = get_errno(extattr_get_fd(arg1, arg2, a, d, arg5)); + unlock_user(d, arg4, arg5); + } else { + ret = get_errno(extattr_get_fd(arg1, arg2, a, NULL, arg5)); + } + unlock_user(a, arg3, 0); + + return ret; +} + +/* extattr_delete_fd(2) */ +static inline abi_long do_freebsd_extattr_delete_fd(abi_long arg1, + abi_long arg2, + abi_ulong arg3) +{ + abi_long ret; + void *a; + + a = lock_user_string(arg3); + if (a == NULL) { + return -TARGET_EFAULT; + } + ret = get_errno(extattr_delete_fd(arg1, arg2, a)); + unlock_user(a, arg3, 0); + + return ret; +} + + +#endif /* FREEBSD_OS_EXTATTR_H */ -- 2.52.0
