summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2004-08-25 17:24:19 +0000
committerManuel Novoa III <mjn3@codepoet.org>2004-08-25 17:24:19 +0000
commitf2916400b6b3f4ad4a80f9c865a132d6b7fb4d9a (patch)
tree8a77241882908ba73960ce105717722e34d178ea /libc/sysdeps/linux
parentac5506822324b3734549fb5633166af3d5eb9365 (diff)
Patch by Carl SHAW <carl.shaw@st.com>...
Below is a patch to make the pread and pwrite calls work on the SH architecture. I've only tested this on the SH4 with a 2.4.24 kernel - a fairly recent kernel is required as the problem is partially fixed in the kernel itself. For more information (in relation to glibc, but the problem is the same) see the thread at http://sourceforge.net/mailarchive/message.php?msg_id=2375908 Someone should really test this on the SH2/3...
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r--libc/sysdeps/linux/sh/Makefile2
-rw-r--r--libc/sysdeps/linux/sh/pread_write.c106
2 files changed, 107 insertions, 1 deletions
diff --git a/libc/sysdeps/linux/sh/Makefile b/libc/sysdeps/linux/sh/Makefile
index 5382d5b5a..fff757d5a 100644
--- a/libc/sysdeps/linux/sh/Makefile
+++ b/libc/sysdeps/linux/sh/Makefile
@@ -31,7 +31,7 @@ CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
SSRC=setjmp.S __longjmp.S vfork.S clone.S
SOBJS=$(patsubst %.S,%.o, $(SSRC))
-CSRC=mmap.c longjmp.c pipe.c __init_brk.c brk.c sbrk.c syscall.c
+CSRC=mmap.c longjmp.c pipe.c __init_brk.c brk.c sbrk.c syscall.c pread_write.c
COBJS=$(patsubst %.c,%.o, $(CSRC))
OBJS=$(SOBJS) $(MOBJ) $(COBJS)
diff --git a/libc/sysdeps/linux/sh/pread_write.c b/libc/sysdeps/linux/sh/pread_write.c
new file mode 100644
index 000000000..55b234855
--- /dev/null
+++ b/libc/sysdeps/linux/sh/pread_write.c
@@ -0,0 +1,106 @@
+/* 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>
+#include <stdint.h>
+
+#ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_pread
+# error "__NR_pread and __NR_pread64 both defined???"
+# endif
+# define __NR_pread __NR_pread64
+#endif
+
+#ifdef __NR_pread
+
+
+#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)
+{
+ uint32_t low = offset & 0xffffffff;
+ uint32_t high = offset >> 32;
+ return(__syscall_pread(fd, buf, count, 0, __LONG_LONG_PAIR (high, low)));
+}
+weak_alias (__libc_pread64, pread64)
+#endif /* __UCLIBC_HAS_LFS__ */
+
+#endif /* __NR_pread */
+
+/**********************************************************************/
+
+#ifdef __NR_pwrite64 /* Newer kernels renamed but it's the same. */
+# ifdef __NR_pwrite
+# error "__NR_pwrite and __NR_pwrite64 both defined???"
+# endif
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+#ifdef __NR_pwrite
+
+#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)
+{
+ uint32_t low = offset & 0xffffffff;
+ uint32_t high = offset >> 32;
+ return(__syscall_pwrite(fd, buf, count, 0, __LONG_LONG_PAIR (high, low)));
+}
+weak_alias (__libc_pwrite64, pwrite64)
+#endif /* __UCLIBC_HAS_LFS__ */
+
+#endif /* __NR_pwrite */