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 | |
parent | dfae8e00f8ddeedcda24bd28f71d4fd2a9f988b8 (diff) | |
download | qemu-a8fd1aba8584cbe68583907ce766fd8ecfe81f4b.zip |
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>
-rwxr-xr-x | configure | 17 | ||||
-rw-r--r-- | linux-user/syscall.c | 53 |
2 files changed, 70 insertions, 0 deletions
@@ -2760,6 +2760,20 @@ if compile_prog "" "" ; then epoll_pwait=yes fi +# check for sendfile support +sendfile=no +cat > $TMPC << EOF +#include <sys/sendfile.h> + +int main(void) +{ + return sendfile(0, 0, 0, 0); +} +EOF +if compile_prog "" "" ; then + sendfile=yes +fi + # Check if tools are available to build documentation. if test "$docs" != "no" ; then if has makeinfo && has pod2man; then @@ -3628,6 +3642,9 @@ fi if test "$epoll_pwait" = "yes" ; then echo "CONFIG_EPOLL_PWAIT=y" >> $config_host_mak fi +if test "$sendfile" = "yes" ; then + echo "CONFIG_SENDFILE=y" >> $config_host_mak +fi if test "$inotify" = "yes" ; then echo "CONFIG_INOTIFY=y" >> $config_host_mak fi 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; |