diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2013-02-08 07:31:55 +0000 |
---|---|---|
committer | Riku Voipio <riku.voipio@linaro.org> | 2013-03-11 14:34:28 +0200 |
commit | a8fd1aba8584cbe68583907ce766fd8ecfe81f4b (patch) | |
tree | 4ded77320c1ecdda9340c8ec776f56fa024b6261 /linux-user/syscall.c | |
parent | dfae8e00f8ddeedcda24bd28f71d4fd2a9f988b8 (diff) |
linux-user: Implement sendfile and sendfile64
Implement the sendfile and sendfile64 syscalls. This implementation
passes all the LTP test cases for these syscalls.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r-- | linux-user/syscall.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index bab9ab58a0..77281f1b48 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -78,6 +78,9 @@ int __clone2(int (*fn)(void *), void *child_stack_base, #ifdef CONFIG_ATTR #include "qemu/xattr.h" #endif +#ifdef CONFIG_SENDFILE +#include <sys/sendfile.h> +#endif #define termios host_termios #define winsize host_winsize @@ -7531,8 +7534,58 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #else goto unimplemented; #endif + +#ifdef CONFIG_SENDFILE + case TARGET_NR_sendfile: + { + off_t *offp = NULL; + off_t off; + if (arg3) { + ret = get_user_sal(off, arg3); + if (is_error(ret)) { + break; + } + offp = &off; + } + ret = get_errno(sendfile(arg1, arg2, offp, arg4)); + if (!is_error(ret) && arg3) { + abi_long ret2 = put_user_sal(off, arg3); + if (is_error(ret2)) { + ret = ret2; + } + } + break; + } +#ifdef TARGET_NR_sendfile64 + case TARGET_NR_sendfile64: + { + off_t *offp = NULL; + off_t off; + if (arg3) { + ret = get_user_s64(off, arg3); + if (is_error(ret)) { + break; + } + offp = &off; + } + ret = get_errno(sendfile(arg1, arg2, offp, arg4)); + if (!is_error(ret) && arg3) { + abi_long ret2 = put_user_s64(off, arg3); + if (is_error(ret2)) { + ret = ret2; + } + } + break; + } +#endif +#else case TARGET_NR_sendfile: +#ifdef TARGET_NR_sendfile64: + case TARGET_NR_sendfile64: +#endif goto unimplemented; +#endif + #ifdef TARGET_NR_getpmsg case TARGET_NR_getpmsg: goto unimplemented; |