diff options
author | Eric Andersen <andersen@codepoet.org> | 2003-08-22 03:05:06 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2003-08-22 03:05:06 +0000 |
commit | 55f313d4e2479e7edbc64c7537023f47c44a81c3 (patch) | |
tree | af88be2144ff3b52e3b6e55de595f39b962c8267 /libc/sysdeps | |
parent | f9c09888823fa659fcfe43eaa816a7a9ddbd04eb (diff) |
Patch from Atsushi Nemoto, who writes:
I found that current pread/pwrite is broken on mips.
On mips, kernel needs 6 arguments for pread/pwrite system call. (3
words for first 3 arguments + 1 padding word + 2 words for last 64bit
argument). Also, mips64 kernel needs just 4 arguments so no wrapper
will be required.
This is a patch against 0.9.20.
Diffstat (limited to 'libc/sysdeps')
-rw-r--r-- | libc/sysdeps/linux/mips/Makefile | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/mips/pread_write.c | 94 |
2 files changed, 95 insertions, 1 deletions
diff --git a/libc/sysdeps/linux/mips/Makefile b/libc/sysdeps/linux/mips/Makefile index 85c605aa8..eaeff33b7 100644 --- a/libc/sysdeps/linux/mips/Makefile +++ b/libc/sysdeps/linux/mips/Makefile @@ -26,7 +26,7 @@ CRT0_OBJ = crt0.o crt1.o SSRC=bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S fork.S syscall.S pipe.S SOBJS=$(patsubst %.S,%.o, $(SSRC)) -CSRC=__longjmp.c brk.c vfork.c setjmp_aux.c _mmap.c __syscall_error.c cacheflush.c +CSRC=__longjmp.c brk.c vfork.c setjmp_aux.c _mmap.c __syscall_error.c cacheflush.c pread_write.c COBJS=$(patsubst %.c,%.o, $(CSRC)) OBJS=$(SOBJS) $(MOBJ) $(COBJS) diff --git a/libc/sysdeps/linux/mips/pread_write.c b/libc/sysdeps/linux/mips/pread_write.c new file mode 100644 index 000000000..a182ebefe --- /dev/null +++ b/libc/sysdeps/linux/mips/pread_write.c @@ -0,0 +1,94 @@ +/* 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 + * sysdeps/posix/pwrite.c + * 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 + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License + * for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define _GNU_SOURCE +#define _LARGEFILE64_SOURCE +#include <features.h> +#undef __OPTIMIZE__ +/* We absolutely do _NOT_ want interfaces silently + * * * renamed under us or very bad things will happen... */ +#ifdef __USE_FILE_OFFSET64 +# undef __USE_FILE_OFFSET64 +#endif + + +#include <errno.h> +#include <sys/types.h> +#include <sys/syscall.h> +#include <unistd.h> + +#ifdef __NR_pread + +#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); + +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))); +} +weak_alias (__libc_pread, pread) + +#if defined __UCLIBC_HAS_LFS__ +ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset) +{ + return(__syscall_pread(fd, buf, count, 0, + __LONG_LONG_PAIR((off_t)(offset>>32),(off_t)(offset&0xffffffff)))); +} +weak_alias (__libc_pread64, pread64) +#endif /* __UCLIBC_HAS_LFS__ */ +#endif /* !__mips64 */ + +#endif /* __NR_pread */ + + +#ifdef __NR_pwrite + +#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); + +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))); +} +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) +{ + return(__syscall_pwrite(fd, buf, count, 0, + __LONG_LONG_PAIR((off_t)(offset>>32),(off_t)(offset&0xffffffff)))); +} +weak_alias (__libc_pwrite64, pwrite64) +#endif /* __UCLIBC_HAS_LFS__ */ +#endif /* !__mips64 */ +#endif /* __NR_pwrite */ |