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>
This commit is contained in:
Peter Maydell 2013-02-08 07:31:55 +00:00 committed by Riku Voipio
parent dfae8e00f8
commit a8fd1aba85
2 changed files with 70 additions and 0 deletions

17
configure vendored
View File

@ -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

View File

@ -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;