Patchwork linux-user: Implement sendfile and sendfile64

login
register
mail settings
Submitter Peter Maydell
Date Feb. 8, 2013, 5:31 p.m.
Message ID <1360344715-2442-1-git-send-email-peter.maydell@linaro.org>
Download mbox | patch
Permalink /patch/219229/
State New
Headers show

Comments

Peter Maydell - Feb. 8, 2013, 5:31 p.m.
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>
---
This test-driven-development thing is fun :-)

 configure            |   17 ++++++++++++++++
 linux-user/syscall.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+)
Richard Henderson - Feb. 8, 2013, 8:23 p.m.
On 2013-02-08 09:31, Peter Maydell wrote:
> 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>
> ---
> This test-driven-development thing is fun :-)
>
>   configure            |   17 ++++++++++++++++
>   linux-user/syscall.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 70 insertions(+)
>
Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

Patch

diff --git a/configure b/configure
index 8789324..fd64e82 100755
--- a/configure
+++ b/configure
@@ -2715,6 +2715,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
@@ -3551,6 +3565,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 fcdccfa..35df073 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
@@ -7551,8 +7554,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;