[prev in list] [next in list] [prev in thread] [next in thread] 

List:       uclibc
Subject:    [PATCH v3 27/48] sendfile: Use sendfile64 if arch does not have the sendfile syscall
From:       Markos Chandras <markos.chandras () gmail ! com>
Date:       2013-01-23 11:41:51
Message-ID: 1358941332-6190-28-git-send-email-markos.chandras () gmail ! com
[Download RAW message or body]

From: Markos Chandras <markos.chandras@imgtec.com>

Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
---
 include/sys/sendfile.h                 |  1 +
 libc/sysdeps/linux/common/sendfile.c   | 48 +++++++++++++++++++++++++++++++---
 libc/sysdeps/linux/common/sendfile64.c |  1 +
 libc/sysdeps/linux/common/stubs.c      |  3 ++-
 4 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/include/sys/sendfile.h b/include/sys/sendfile.h
index dd6c034..dae074c 100644
--- a/include/sys/sendfile.h
+++ b/include/sys/sendfile.h
@@ -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
diff --git a/libc/sysdeps/linux/common/sendfile.c b/libc/sysdeps/linux/common/sendfile.c
index 64c200e..82fdd3d 100644
--- a/libc/sysdeps/linux/common/sendfile.c
+++ b/libc/sysdeps/linux/common/sendfile.c
@@ -9,12 +9,54 @@
 
 #include <sys/syscall.h>
 
-#ifdef __NR_sendfile
-# include <sys/sendfile.h>
-# include <bits/wordsize.h>
+#include <sys/sendfile.h>
+#include <bits/wordsize.h>
+#include <unistd.h>
+#include <stddef.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)
+ssize_t sendfile(int out_fd, int in_fd, __off_t *offset, size_t count)
+{
+	__off64_t off64, *off;
+	ssize_t res;
+
+	/*
+	 * Check if valids fd 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
diff --git a/libc/sysdeps/linux/common/sendfile64.c b/libc/sysdeps/linux/common/sendfile64.c
index 705e6fd..1c01ace 100644
--- a/libc/sysdeps/linux/common/sendfile64.c
+++ b/libc/sysdeps/linux/common/sendfile64.c
@@ -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
diff --git a/libc/sysdeps/linux/common/stubs.c b/libc/sysdeps/linux/common/stubs.c
index 856b08a..9f01714 100644
--- a/libc/sysdeps/linux/common/stubs.c
+++ b/libc/sysdeps/linux/common/stubs.c
@@ -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
 
-- 
1.8.1.1


_______________________________________________
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic