OSDN Git Service

sendfile: Use sendfile64 if arch does not have the sendfile syscall
authorMarkos Chandras <markos.chandras@imgtec.com>
Thu, 11 Oct 2012 10:20:42 +0000 (11:20 +0100)
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Wed, 20 Feb 2013 12:45:12 +0000 (13:45 +0100)
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
include/sys/sendfile.h
libc/sysdeps/linux/common/sendfile.c
libc/sysdeps/linux/common/sendfile64.c
libc/sysdeps/linux/common/stubs.c

index dd6c034..dae074c 100644 (file)
@@ -44,6 +44,7 @@ extern ssize_t __REDIRECT_NTH (sendfile,
 #ifdef __USE_LARGEFILE64
 extern ssize_t sendfile64 (int __out_fd, int __in_fd, __off64_t *__offset,
                           size_t __count) __THROW;
+libc_hidden_proto(sendfile64)
 #endif
 
 __END_DECLS
index 64c200e..2bd7179 100644 (file)
@@ -9,12 +9,55 @@
 
 #include <sys/syscall.h>
 
-#ifdef __NR_sendfile
 # include <sys/sendfile.h>
 # include <bits/wordsize.h>
+
+#if defined __NR_sendfile
 _syscall4(ssize_t, sendfile, int, out_fd, int, in_fd, __off_t *, offset,
          size_t, count)
 # if defined __UCLIBC_HAS_LFS__ && (!defined __NR_sendfile64 || __WORDSIZE == 64)
 strong_alias_untyped(sendfile,sendfile64)
 # endif
+
+#elif defined __NR_sendfile64 && !defined __NR_sendfile
+# include <unistd.h>
+# include <stddef.h>
+
+ssize_t sendfile(int out_fd, int in_fd, __off_t *offset, size_t count)
+{
+       __off64_t off64, *off;
+       ssize_t res;
+
+       /*
+        * Check if valid fds and valid pointers were passed
+        * This does not prevent the user from passing
+        * an arbitrary pointer causing a segfault or
+        * other security issues
+        */
+
+       if (in_fd < 0 || out_fd < 0) {
+               __set_errno(EBADF);
+               return -1;
+       }
+
+       if (offset == NULL || (int)offset < 0) {
+               __set_errno(EFAULT);
+               return -1;
+       }
+
+       if (offset) {
+               off = &off64;
+               off64 = *offset;
+       } else {
+               off = NULL;
+       }
+
+       res = INLINE_SYSCALL(sendfile64, 4, out_fd, in_fd, off, count);
+
+       if (res >= 0)
+               *offset = off64;
+
+       return res;
+}
+
 #endif
index 705e6fd..1c01ace 100644 (file)
@@ -17,4 +17,5 @@
 #if defined __NR_sendfile64 && __WORDSIZE != 64
 # include <sys/sendfile.h>
 _syscall4(ssize_t,sendfile64, int, out_fd, int, in_fd, __off64_t *, offset, size_t, count)
+libc_hidden_def(sendfile64)
 #endif
index 419557c..43a1b69 100644 (file)
@@ -320,7 +320,8 @@ make_stub(sched_setaffinity)
 make_stub(send)
 #endif
 
-#if !defined __NR_sendfile && defined __UCLIBC_LINUX_SPECIFIC__
+#if !defined __NR_sendfile && !defined __NR_sendfile64 \
+       && defined __UCLIBC_LINUX_SPECIFIC__
 make_stub(sendfile)
 #endif