diff options
author | Markos Chandras <markos.chandras@imgtec.com> | 2012-10-11 11:20:42 +0100 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2013-02-20 13:45:12 +0100 |
commit | a83ea57a508362f8f66ecd89131302fba1223637 (patch) | |
tree | 18dbdf27ad89846869afc61dc33edfa085c85c57 /libc/sysdeps/linux/common | |
parent | f7bead5adac96d9cb72aa2fb3c11ca5ab8f5f6b9 (diff) |
sendfile: Use sendfile64 if arch does not have the sendfile syscall
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Diffstat (limited to 'libc/sysdeps/linux/common')
-rw-r--r-- | libc/sysdeps/linux/common/sendfile.c | 45 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/sendfile64.c | 1 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/stubs.c | 3 |
3 files changed, 47 insertions, 2 deletions
diff --git a/libc/sysdeps/linux/common/sendfile.c b/libc/sysdeps/linux/common/sendfile.c index 64c200eb2..2bd717929 100644 --- a/libc/sysdeps/linux/common/sendfile.c +++ b/libc/sysdeps/linux/common/sendfile.c @@ -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 diff --git a/libc/sysdeps/linux/common/sendfile64.c b/libc/sysdeps/linux/common/sendfile64.c index 705e6fdee..1c01ace7f 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 419557c6a..43a1b6938 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 |