|
@@ -1,219 +0,0 @@
|
|
-From 342a3d861fde5651ee53486addbacddcec6a0a58 Mon Sep 17 00:00:00 2001
|
|
|
|
-From: Natanael Copa <natanael.copa@gmail.com>
|
|
|
|
-Date: Sat, 4 Aug 2012 19:32:45 +0200
|
|
|
|
-Subject: [PATCH] pread/pwrite: backport fix
|
|
|
|
-
|
|
|
|
-pread/pwrite syscalls has been renamed to pread64/pwrite in 2.6 kernel.
|
|
|
|
-
|
|
|
|
-There was a fallback function using lseek for kernels who did not have
|
|
|
|
-this syscall (pre 2.1.60). This is broken in many ways.
|
|
|
|
-
|
|
|
|
-uclibc have been using the broken fallback due to they forgot to rename
|
|
|
|
-pread syscall.
|
|
|
|
-
|
|
|
|
-This got detected with git-1.7.11 which introduced threaded index-pack
|
|
|
|
-which broke in similar ways a windows (msys).
|
|
|
|
-
|
|
|
|
-This issue in uclibc have been reported upstream and fixed in git master
|
|
|
|
-so this patch does not need to be upstreamed. It might be an idea to
|
|
|
|
-backport it properly for 0.9.33 branch though.
|
|
|
|
-
|
|
|
|
-Signed-off-by: Natanael Copa <natanael.copa@gmail.com>
|
|
|
|
-Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
|
|
|
|
----
|
|
|
|
- libc/sysdeps/linux/common/pread_write.c | 143 ++++---------------------------
|
|
|
|
- 1 file changed, 19 insertions(+), 124 deletions(-)
|
|
|
|
-
|
|
|
|
-diff --git a/libc/sysdeps/linux/common/pread_write.c b/libc/sysdeps/linux/common/pread_write.c
|
|
|
|
-index 88e6957..baf8691 100644
|
|
|
|
---- a/libc/sysdeps/linux/common/pread_write.c
|
|
|
|
-+++ b/libc/sysdeps/linux/common/pread_write.c
|
|
|
|
-@@ -17,6 +17,7 @@
|
|
|
|
- #include <unistd.h>
|
|
|
|
- #include <stdint.h>
|
|
|
|
- #include <endian.h>
|
|
|
|
-+#include <sysdep-cancel.h>
|
|
|
|
-
|
|
|
|
- extern __typeof(pread) __libc_pread;
|
|
|
|
- extern __typeof(pwrite) __libc_pwrite;
|
|
|
|
-@@ -27,15 +28,17 @@ extern __typeof(pwrite64) __libc_pwrite64;
|
|
|
|
-
|
|
|
|
- #include <bits/kernel_types.h>
|
|
|
|
-
|
|
|
|
--#ifdef __NR_pread
|
|
|
|
--
|
|
|
|
--# define __NR___syscall_pread __NR_pread
|
|
|
|
-+# define __NR___syscall_pread __NR_pread64
|
|
|
|
- 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)
|
|
|
|
- {
|
|
|
|
-- return __syscall_pread(fd, buf, count, __LONG_LONG_PAIR(offset >> 31, 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;
|
|
|
|
-+
|
|
|
|
- }
|
|
|
|
- weak_alias(__libc_pread,pread)
|
|
|
|
-
|
|
|
|
-@@ -44,22 +47,24 @@ 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, __LONG_LONG_PAIR(high, low));
|
|
|
|
-+ int oldtype = LIBC_CANCEL_ASYNC ();
|
|
|
|
-+ int result = __syscall_pread(fd, buf, count, __LONG_LONG_PAIR(high, low));
|
|
|
|
-+ LIBC_CANCEL_RESET (oldtype);
|
|
|
|
-+ return result;
|
|
|
|
- }
|
|
|
|
- weak_alias(__libc_pread64,pread64)
|
|
|
|
- # endif /* __UCLIBC_HAS_LFS__ */
|
|
|
|
-
|
|
|
|
--#endif /* __NR_pread */
|
|
|
|
--
|
|
|
|
--#ifdef __NR_pwrite
|
|
|
|
--
|
|
|
|
--# define __NR___syscall_pwrite __NR_pwrite
|
|
|
|
-+# define __NR___syscall_pwrite __NR_pwrite64
|
|
|
|
- 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)
|
|
|
|
- {
|
|
|
|
-- return __syscall_pwrite(fd, buf, count, __LONG_LONG_PAIR(offset >> 31, 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;
|
|
|
|
- }
|
|
|
|
- weak_alias(__libc_pwrite,pwrite)
|
|
|
|
-
|
|
|
|
-@@ -68,120 +73,10 @@ 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, __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);
|
|
|
|
-+ int oldtype = LIBC_CANCEL_ASYNC ();
|
|
|
|
-+ int result = __syscall_pwrite(fd, buf, count, __LONG_LONG_PAIR(high, low));
|
|
|
|
-+ LIBC_CANCEL_RESET (oldtype);
|
|
|
|
- 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.10.4
|
|
|
|
-
|
|
|