[PATCH 0.9.33 1/7] Revert "pread/pwrite: backport fix"
Natanael Copa
natanael.copa at gmail.com
Wed Aug 29 09:18:58 UTC 2012
This backport breaks x86_64 badly.
This reverts commit 342a3d861fde5651ee53486addbacddcec6a0a58.
Signed-off-by: Natanael Copa <ncopa at alpinelinux.org>
---
libc/sysdeps/linux/common/pread_write.c | 143 +++++++++++++++++++++++++++-----
1 file changed, 124 insertions(+), 19 deletions(-)
diff --git a/libc/sysdeps/linux/common/pread_write.c b/libc/sysdeps/linux/common/pread_write.c
index baf8691..88e6957 100644
--- a/libc/sysdeps/linux/common/pread_write.c
+++ b/libc/sysdeps/linux/common/pread_write.c
@@ -17,7 +17,6 @@
#include <unistd.h>
#include <stdint.h>
#include <endian.h>
-#include <sysdep-cancel.h>
extern __typeof(pread) __libc_pread;
extern __typeof(pwrite) __libc_pwrite;
@@ -28,17 +27,15 @@ extern __typeof(pwrite64) __libc_pwrite64;
#include <bits/kernel_types.h>
-# define __NR___syscall_pread __NR_pread64
+#ifdef __NR_pread
+
+# define __NR___syscall_pread __NR_pread
static __inline__ _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf,
size_t, count, off_t, offset_hi, off_t, offset_lo)
ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
{
- int oldtype = LIBC_CANCEL_ASYNC ();
- int result = __syscall_pread(fd, buf, count, __LONG_LONG_PAIR(offset >> 31, offset));
- LIBC_CANCEL_RESET (oldtype);
- return result;
-
+ return __syscall_pread(fd, buf, count, __LONG_LONG_PAIR(offset >> 31, offset));
}
weak_alias(__libc_pread,pread)
@@ -47,24 +44,22 @@ ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
{
uint32_t low = offset & 0xffffffff;
uint32_t high = offset >> 32;
- int oldtype = LIBC_CANCEL_ASYNC ();
- int result = __syscall_pread(fd, buf, count, __LONG_LONG_PAIR(high, low));
- LIBC_CANCEL_RESET (oldtype);
- return result;
+ return __syscall_pread(fd, buf, count, __LONG_LONG_PAIR(high, low));
}
weak_alias(__libc_pread64,pread64)
# endif /* __UCLIBC_HAS_LFS__ */
-# define __NR___syscall_pwrite __NR_pwrite64
+#endif /* __NR_pread */
+
+#ifdef __NR_pwrite
+
+# define __NR___syscall_pwrite __NR_pwrite
static __inline__ _syscall5(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
size_t, count, off_t, offset_hi, off_t, offset_lo)
ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
{
- int oldtype = LIBC_CANCEL_ASYNC ();
- int result = __syscall_pwrite(fd, buf, count, __LONG_LONG_PAIR(offset >> 31, offset));
- LIBC_CANCEL_RESET (oldtype);
- return result;
+ return __syscall_pwrite(fd, buf, count, __LONG_LONG_PAIR(offset >> 31, offset));
}
weak_alias(__libc_pwrite,pwrite)
@@ -73,10 +68,120 @@ 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;
- int oldtype = LIBC_CANCEL_ASYNC ();
- int result = __syscall_pwrite(fd, buf, count, __LONG_LONG_PAIR(high, low));
- LIBC_CANCEL_RESET (oldtype);
+ return __syscall_pwrite(fd, buf, count, __LONG_LONG_PAIR(high, low));
+}
+weak_alias(__libc_pwrite64,pwrite64)
+# endif /* __UCLIBC_HAS_LFS__ */
+#endif /* __NR_pwrite */
+
+#if ! defined __NR_pread || ! defined __NR_pwrite
+
+static ssize_t __fake_pread_write(int fd, void *buf,
+ size_t count, off_t offset, int do_pwrite)
+{
+ int save_errno;
+ ssize_t result;
+ off_t old_offset;
+
+ /* Since we must not change the file pointer preserve the
+ * value so that we can restore it later. */
+ if ((old_offset=lseek(fd, 0, SEEK_CUR)) == (off_t) -1)
+ return -1;
+
+ /* Set to wanted position. */
+ if (lseek(fd, offset, SEEK_SET) == (off_t) -1)
+ return -1;
+
+ if (do_pwrite == 1) {
+ /* Write the data. */
+ result = write(fd, buf, count);
+ } else {
+ /* Read the data. */
+ result = read(fd, buf, count);
+ }
+
+ /* Now we have to restore the position. If this fails we
+ * have to return this as an error. */
+ save_errno = errno;
+ if (lseek(fd, old_offset, SEEK_SET) == (off_t) -1)
+ {
+ if (result == -1)
+ __set_errno(save_errno);
+ return -1;
+ }
+ __set_errno(save_errno);
+ return(result);
+}
+
+# ifdef __UCLIBC_HAS_LFS__
+
+static ssize_t __fake_pread_write64(int fd, void *buf,
+ size_t count, off64_t offset, int do_pwrite)
+{
+ int save_errno;
+ ssize_t result;
+ off64_t old_offset;
+
+ /* Since we must not change the file pointer preserve the
+ * value so that we can restore it later. */
+ if ((old_offset=lseek64(fd, 0, SEEK_CUR)) == (off64_t) -1)
+ return -1;
+
+ /* Set to wanted position. */
+ if (lseek64(fd, offset, SEEK_SET) == (off64_t) -1)
+ return -1;
+
+ if (do_pwrite == 1) {
+ /* Write the data. */
+ result = write(fd, buf, count);
+ } else {
+ /* Read the data. */
+ result = read(fd, buf, count);
+ }
+
+ /* Now we have to restore the position. */
+ save_errno = errno;
+ if (lseek64(fd, old_offset, SEEK_SET) == (off64_t) -1) {
+ if (result == -1)
+ __set_errno (save_errno);
+ return -1;
+ }
+ __set_errno (save_errno);
return result;
}
+# endif /* __UCLIBC_HAS_LFS__ */
+#endif /* ! defined __NR_pread || ! defined __NR_pwrite */
+
+#ifndef __NR_pread
+ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
+{
+ return __fake_pread_write(fd, buf, count, offset, 0);
+}
+weak_alias(__libc_pread,pread)
+
+# ifdef __UCLIBC_HAS_LFS__
+ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
+{
+ return __fake_pread_write64(fd, buf, count, offset, 0);
+}
+weak_alias(__libc_pread64,pread64)
+# endif /* __UCLIBC_HAS_LFS__ */
+#endif /* ! __NR_pread */
+
+#ifndef __NR_pwrite
+ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
+{
+ /* we won't actually be modifying the buffer,
+ *just cast it to get rid of warnings */
+ return __fake_pread_write(fd, (void*)buf, count, offset, 1);
+}
+weak_alias(__libc_pwrite,pwrite)
+
+# ifdef __UCLIBC_HAS_LFS__
+ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
+{
+ return __fake_pread_write64(fd, (void*)buf, count, offset, 1);
+}
weak_alias(__libc_pwrite64,pwrite64)
# endif /* __UCLIBC_HAS_LFS__ */
+#endif /* ! __NR_pwrite */
--
1.7.12
More information about the uClibc
mailing list