aboutsummaryrefslogtreecommitdiff
path: root/libc/bionic/legacy_32_bit_support.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libc/bionic/legacy_32_bit_support.cpp')
-rw-r--r--libc/bionic/legacy_32_bit_support.cpp19
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));