diff options
Diffstat (limited to 'libc/bionic/legacy_32_bit_support.cpp')
-rw-r--r-- | libc/bionic/legacy_32_bit_support.cpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/libc/bionic/legacy_32_bit_support.cpp b/libc/bionic/legacy_32_bit_support.cpp index 41108e6af..f08e58266 100644 --- a/libc/bionic/legacy_32_bit_support.cpp +++ b/libc/bionic/legacy_32_bit_support.cpp @@ -45,6 +45,8 @@ // System calls we need. extern "C" int __llseek(int, unsigned long, unsigned long, off64_t*, int); +extern "C" int __preadv64(int, const struct iovec*, int, long, long); +extern "C" int __pwritev64(int, const struct iovec*, int, long, long); // For lseek64 we need to use the llseek system call which splits the off64_t in two and // returns the off64_t result via a pointer because 32-bit kernels can't return 64-bit results. @@ -68,6 +70,23 @@ ssize_t pwrite(int fd, const void* buf, size_t byte_count, off_t offset) { return pwrite64(fd, buf, byte_count, static_cast<off64_t>(offset)); } +// On LP32, there is no off_t preadv/pwritev, and even the 64-bit preadv/pwritev +// don't use off64_t (see SYSCALLS.TXT for more). Here, this means that we need +// to implement all four functions because the two system calls don't match any +// of the userspace functions. Unlike llseek, the pair is split lo-hi, not hi-lo. +ssize_t preadv(int fd, const struct iovec* ios, int count, off_t offset) { + return preadv64(fd, ios, count, offset); +} +ssize_t preadv64(int fd, const struct iovec* ios, int count, off64_t offset) { + return __preadv64(fd, ios, count, offset, offset >> 32); +} +ssize_t pwritev(int fd, const struct iovec* ios, int count, off_t offset) { + return pwritev64(fd, ios, count, offset); +} +ssize_t pwritev64(int fd, const struct iovec* ios, int count, off64_t offset) { + return __pwritev64(fd, ios, count, offset, offset >> 32); +} + // There is no fallocate for 32-bit off_t, so we need to widen and call fallocate64. int fallocate(int fd, int mode, off_t offset, off_t length) { return fallocate64(fd, mode, static_cast<off64_t>(offset), static_cast<off64_t>(length)); |