diff options
author | An-Cheng Huang <ancheng@ubnt.com> | 2011-08-09 12:34:06 -0700 |
---|---|---|
committer | Riku Voipio <riku.voipio@linaro.org> | 2011-09-09 10:48:03 +0300 |
commit | a790ae389bf779424789dc6ddc946ea268d58c42 (patch) | |
tree | 0ee7293a6a47c3931cd1e94909c84123e05a43c6 /linux-user | |
parent | 94c19610a6973ad917d9c154eabfc2ee27bc4f59 (diff) | |
download | qemu-a790ae389bf779424789dc6ddc946ea268d58c42.tar.gz qemu-a790ae389bf779424789dc6ddc946ea268d58c42.tar.bz2 qemu-a790ae389bf779424789dc6ddc946ea268d58c42.zip |
linux-user: Implement setxattr/getxattr/removexattr syscalls
This patch implements the setxattr, getxattr, and removexattr syscalls
if CONFIG_ATTR is enabled.
Note that since libattr uses indirect syscalls for these, this change
depends on the fix for indirect syscall handling on MIPS.
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: An-Cheng Huang <ancheng@ubnt.com>
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/syscall.c | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ae08c9e538..39a34db4b1 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -70,6 +70,9 @@ int __clone2(int (*fn)(void *), void *child_stack_base, #ifdef CONFIG_EPOLL #include <sys/epoll.h> #endif +#ifdef CONFIG_ATTR +#include <attr/xattr.h> +#endif #define termios host_termios #define winsize host_winsize @@ -7642,22 +7645,67 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif break; #endif +#ifdef CONFIG_ATTR #ifdef TARGET_NR_setxattr - case TARGET_NR_setxattr: case TARGET_NR_lsetxattr: case TARGET_NR_fsetxattr: - case TARGET_NR_getxattr: case TARGET_NR_lgetxattr: case TARGET_NR_fgetxattr: case TARGET_NR_listxattr: case TARGET_NR_llistxattr: case TARGET_NR_flistxattr: - case TARGET_NR_removexattr: case TARGET_NR_lremovexattr: case TARGET_NR_fremovexattr: ret = -TARGET_EOPNOTSUPP; break; + case TARGET_NR_setxattr: + { + void *p, *n, *v; + p = lock_user_string(arg1); + n = lock_user_string(arg2); + v = lock_user(VERIFY_READ, arg3, arg4, 1); + if (p && n && v) { + ret = get_errno(setxattr(p, n, v, arg4, arg5)); + } else { + ret = -TARGET_EFAULT; + } + unlock_user(p, arg1, 0); + unlock_user(n, arg2, 0); + unlock_user(v, arg3, 0); + } + break; + case TARGET_NR_getxattr: + { + void *p, *n, *v; + p = lock_user_string(arg1); + n = lock_user_string(arg2); + v = lock_user(VERIFY_WRITE, arg3, arg4, 0); + if (p && n && v) { + ret = get_errno(getxattr(p, n, v, arg4)); + } else { + ret = -TARGET_EFAULT; + } + unlock_user(p, arg1, 0); + unlock_user(n, arg2, 0); + unlock_user(v, arg3, arg4); + } + break; + case TARGET_NR_removexattr: + { + void *p, *n; + p = lock_user_string(arg1); + n = lock_user_string(arg2); + if (p && n) { + ret = get_errno(removexattr(p, n)); + } else { + ret = -TARGET_EFAULT; + } + unlock_user(p, arg1, 0); + unlock_user(n, arg2, 0); + } + break; #endif +#endif /* CONFIG_ATTR */ #ifdef TARGET_NR_set_thread_area case TARGET_NR_set_thread_area: #if defined(TARGET_MIPS) |