diff options
Diffstat (limited to 'libc/sysdeps/linux/sh/pread_write.c')
-rw-r--r-- | libc/sysdeps/linux/sh/pread_write.c | 60 |
1 files changed, 51 insertions, 9 deletions
diff --git a/libc/sysdeps/linux/sh/pread_write.c b/libc/sysdeps/linux/sh/pread_write.c index 9cc4bbf97..ab44204b0 100644 --- a/libc/sysdeps/linux/sh/pread_write.c +++ b/libc/sysdeps/linux/sh/pread_write.c @@ -12,10 +12,17 @@ * from GNU libc 2.2.5, but reworked considerably... */ -#include <sys/syscall.h> +#include "../common/syscalls.h" #include <unistd.h> #include <stdint.h> +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <sysdep-cancel.h> +#else +#define SINGLE_THREAD_P 1 +#endif + + #ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */ # ifdef __NR_pread # error "__NR_pread and __NR_pread64 both defined???" @@ -31,7 +38,15 @@ static inline _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf, ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset) { - return(__syscall_pread(fd,buf,count,0,__LONG_LONG_PAIR((off_t)0,offset))); + if (SINGLE_THREAD_P) + return(__syscall_pread(fd,buf,count,0,__LONG_LONG_PAIR(offset >> 31,offset))); + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ + int oldtype = LIBC_CANCEL_ASYNC (); + ssize_t result = __syscall_pread(fd,buf,count,0,__LONG_LONG_PAIR(offset >> 31,offset)); + LIBC_CANCEL_RESET (oldtype); + return result; +#endif } weak_alias(__libc_pread,pread) @@ -39,9 +54,18 @@ weak_alias(__libc_pread,pread) extern __typeof(pread64) __libc_pread64; ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset) { - uint32_t low = offset & 0xffffffff; - uint32_t high = offset >> 32; - return(__syscall_pread(fd, buf, count, 0, __LONG_LONG_PAIR (high, low))); + uint32_t low = offset & 0xffffffff; + uint32_t high = offset >> 32; + + if (SINGLE_THREAD_P) + return __syscall_pread(fd, buf, count, 0, __LONG_LONG_PAIR (high, low)); + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ + int oldtype = LIBC_CANCEL_ASYNC (); + ssize_t result = __syscall_pread(fd, buf, count, 0, __LONG_LONG_PAIR (high, low)); + LIBC_CANCEL_RESET (oldtype); + return result; +#endif } weak_alias(__libc_pread64,pread64) # endif /* __UCLIBC_HAS_LFS__ */ @@ -64,7 +88,16 @@ static inline _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf, ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset) { - return(__syscall_pwrite(fd,buf,count,0,__LONG_LONG_PAIR((off_t)0,offset))); + if (SINGLE_THREAD_P) + return __syscall_pwrite(fd,buf,count,0,__LONG_LONG_PAIR(offset >> 31,offset)); + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ + int oldtype = LIBC_CANCEL_ASYNC (); + ssize_t result = __syscall_pwrite(fd,buf,count,0,__LONG_LONG_PAIR(offset >> 31,offset)); + LIBC_CANCEL_RESET (oldtype); + return result; +#endif + } weak_alias(__libc_pwrite,pwrite) @@ -72,9 +105,18 @@ weak_alias(__libc_pwrite,pwrite) extern __typeof(pwrite64) __libc_pwrite64; ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset) { - uint32_t low = offset & 0xffffffff; - uint32_t high = offset >> 32; - return(__syscall_pwrite(fd, buf, count, 0, __LONG_LONG_PAIR (high, low))); + uint32_t low = offset & 0xffffffff; + uint32_t high = offset >> 32; + + if (SINGLE_THREAD_P) + return __syscall_pwrite(fd, buf, count, 0, __LONG_LONG_PAIR (high, low)); + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ + int oldtype = LIBC_CANCEL_ASYNC (); + ssize_t result = __syscall_pwrite(fd, buf, count, 0, __LONG_LONG_PAIR (high, low)); + LIBC_CANCEL_RESET (oldtype); + return result; +#endif } weak_alias(__libc_pwrite64,pwrite64) # endif /* __UCLIBC_HAS_LFS__ */ |