From 176fdc735205f009b9c66e498d7b35a0142531c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Thu, 3 Dec 2015 01:44:14 +0100 Subject: [PATCH] linux,fs: fix p{read,write}v with a 64bit offset According to [0] we need to pass it in 2 32bit registers on some platforms such as MIPS. Fix inspired by the musl libc implementation [1]. [0]: http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES [1]: http://git.musl-libc.org/cgit/musl/tree/src/unistd/preadv.c Fixes: https://github.com/libuv/libuv/issues/473 Refs: https://github.com/libuv/libuv/pull/498 Refs: https://github.com/libuv/libuv/pull/627 PR-URL: https://github.com/libuv/libuv/pull/638 Reviewed-By: Ben Noordhuis --- src/unix/linux-syscalls.c | 8 ++++---- src/unix/linux-syscalls.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/unix/linux-syscalls.c b/src/unix/linux-syscalls.c index 566e1f37..89998ded 100644 --- a/src/unix/linux-syscalls.c +++ b/src/unix/linux-syscalls.c @@ -444,18 +444,18 @@ int uv__utimesat(int dirfd, } -ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset) { +ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset) { #if defined(__NR_preadv) - return syscall(__NR_preadv, fd, iov, iovcnt, offset); + return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32)); #else return errno = ENOSYS, -1; #endif } -ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset) { +ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset) { #if defined(__NR_pwritev) - return syscall(__NR_pwritev, fd, iov, iovcnt, offset); + return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32)); #else return errno = ENOSYS, -1; #endif diff --git a/src/unix/linux-syscalls.h b/src/unix/linux-syscalls.h index 6f249b72..96e79439 100644 --- a/src/unix/linux-syscalls.h +++ b/src/unix/linux-syscalls.h @@ -151,8 +151,8 @@ int uv__utimesat(int dirfd, const char* path, const struct timespec times[2], int flags); -ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset); -ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset); +ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset); +ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset); int uv__dup3(int oldfd, int newfd, int flags); #endif /* UV_LINUX_SYSCALL_H_ */