diff options
Diffstat (limited to 'libc/sysdeps/linux/mips/pread_write.c')
-rw-r--r-- | libc/sysdeps/linux/mips/pread_write.c | 190 |
1 files changed, 150 insertions, 40 deletions
diff --git a/libc/sysdeps/linux/mips/pread_write.c b/libc/sysdeps/linux/mips/pread_write.c index 5baba30d2..302dcd64f 100644 --- a/libc/sysdeps/linux/mips/pread_write.c +++ b/libc/sysdeps/linux/mips/pread_write.c @@ -1,12 +1,21 @@ /* vi: set sw=4 ts=4: * - * Copyright (C) 2002 by Erik Andersen <andersen@uclibc.org> - * Based in part on the files - * ./sysdeps/unix/sysv/linux/pwrite.c, - * ./sysdeps/unix/sysv/linux/pread.c, - * sysdeps/posix/pread.c + * Copyright (C) 2006 by Steven J. Hill <sjhill@realitydiluted.com> + * Copyright (C) 2002-2005 by Erik Andersen <andersen@uclibc.org> + * + * New version based heavily on the files: + * sysdeps/linux/sysv/linux/mips/pread.c, + * sysdeps/linux/sysv/linux/mips/pread64.c, + * sysdeps/linux/sysv/linux/mips/pwrite.c, + * sysdeps/linux/sysv/linux/mips/pwrite64.c + * from GNU libc 2.3.5, but with minor rework. + * + * Originally based in part on the files: + * sysdeps/unix/sysv/linux/pwrite.c, + * sysdeps/unix/sysv/linux/pread.c, + * sysdeps/posix/pread.c, * sysdeps/posix/pwrite.c - * from GNU libc 2.2.5, but reworked considerably... + * from GNU libc 2.2.5, but reworked considerably. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by @@ -23,7 +32,6 @@ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define _GNU_SOURCE #define _LARGEFILE64_SOURCE #include <features.h> #undef __OPTIMIZE__ @@ -39,6 +47,10 @@ #include <sys/syscall.h> #include <unistd.h> #include <stdint.h> +#include <assert.h> +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <sysdep-cancel.h> +#endif #ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */ # ifdef __NR_pread @@ -48,30 +60,78 @@ #endif #ifdef __NR_pread +ssize_t +__libc_pread (int fd, void *buf, size_t count, off_t offset) +{ + ssize_t result; + +#if _MIPS_SIM != _ABI64 + assert (sizeof (offset) == 4); +#endif + + if (SINGLE_THREAD_P) + { + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pread, 4, fd, buf, count, offset); +#else + result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0, + __LONG_LONG_PAIR (offset >> 31, offset)); +#endif + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); -#ifdef __mips64 -_syscall4(ssize_t, pread, int, fd, void *, buf, size_t, count, off_t, offset); -#else /* !__mips64 */ -#define __NR___syscall_pread __NR_pread -static inline _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf, - size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo); + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pread, 4, fd, buf,, count, offset); +#else + result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0, + __LONG_LONG_PAIR (offset >> 31, offset)); +#endif + + LIBC_CANCEL_RESET (oldtype); -ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset) -{ - return(__syscall_pread(fd,buf,count,0,__LONG_LONG_PAIR(offset>>31,offset))); + return result; } weak_alias (__libc_pread, pread) #if defined __UCLIBC_HAS_LFS__ -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))); +ssize_t +__libc_pread64 (int fd, void *buf, size_t count, off64_t offset) +{ + ssize_t result; + + if (SINGLE_THREAD_P) + { + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + return INLINE_SYSCALL (pread, 4, fd, buf, count, offset); +#else + return INLINE_SYSCALL (pread, 6, fd, buf, count, 0, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff))); +#endif + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pread, 4, fd, buf, count, offset); +#else + result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff))); +#endif + + LIBC_CANCEL_RESET (oldtype); + + return result; } -weak_alias (__libc_pread64, pread64) +weak_alias(__libc_pread64, pread64) #endif /* __UCLIBC_HAS_LFS__ */ -#endif /* !__mips64 */ #endif /* __NR_pread */ @@ -85,28 +145,78 @@ weak_alias (__libc_pread64, pread64) #endif #ifdef __NR_pwrite +ssize_t +__libc_pwrite (int fd, const void *buf, size_t count, off_t offset) +{ + ssize_t result; + +#if _MIPS_SIM != _ABI64 + assert (sizeof (offset) == 4); +#endif + + if (SINGLE_THREAD_P) + { + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pwrite, 4, fd, buf, count, offset); +#else + result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0, + __LONG_LONG_PAIR (offset >> 31, offset)); +#endif + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pwrite, 4, fd, buf, count, offset); +#else + result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0, + __LONG_LONG_PAIR (offset >> 31, offset)); +#endif -#ifdef __mips64 -_syscall4(ssize_t, pwrite, int, fd, const void *, buf, size_t, count, off_t, offset); -#else /* !__mips64 */ -#define __NR___syscall_pwrite __NR_pwrite -static inline _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf, - size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo); + LIBC_CANCEL_RESET (oldtype); -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(offset>>31,offset))); + return result; } -weak_alias (__libc_pwrite, pwrite) +weak_alias(__libc_pwrite, pwrite) #if defined __UCLIBC_HAS_LFS__ -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))); +ssize_t +__libc_pwrite64 (int fd, const void *buf, size_t count, off64_t offset) +{ + ssize_t result; + + if (SINGLE_THREAD_P) + { + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pwrite, 4, fd, buf, count, offset); +#else + result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff))); +#endif + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + /* First try the syscall. */ +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + result = INLINE_SYSCALL (pwrite, 4, fd, buf, count, offset); +#else + result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0, + __LONG_LONG_PAIR ((off_t) (offset >> 32), + (off_t) (offset & 0xffffffff))); +#endif + + LIBC_CANCEL_RESET (oldtype); + + return result; } -weak_alias (__libc_pwrite64, pwrite64) +weak_alias(__libc_pwrite64, pwrite64) #endif /* __UCLIBC_HAS_LFS__ */ -#endif /* !__mips64 */ + #endif /* __NR_pwrite */ |