Commit a8fd1aba authored by Peter Maydell's avatar Peter Maydell Committed by Riku Voipio
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarRichard Henderson <rth@twiddle.net>
Signed-off-by: default avatarRiku Voipio <riku.voipio@linaro.org>
parent dfae8e00
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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
+53 −0
Original line number Diff line number Diff line
@@ -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;