zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit f9af406341faa2b649e0578d82ae658b38e31a89 (tree)
parent 8bf14231b23fd68b8ce291de4ee563bc30fc4e15
Author: Tw <wei.tan@intel.com>
Date:   Sat, 29 Jan 2022 17:44:13 +0800

Fix preadv/pwritev bug on 64bit platform

Signed-off-by: Tw <wei.tan@intel.com>

Diffstat:
Mlib/std/os/linux.zig | 30++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig @@ -440,26 +440,30 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize { } pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: i64) usize { - const offset_halves = splitValueLE64(offset); + const offset_u = @bitCast(u64, offset); return syscall5( .preadv, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count, - offset_halves[0], - offset_halves[1], + // Kernel expects the offset is splitted into largest natural word-size. + // See following link for detail: + // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=601cc11d054ae4b5e9b5babec3d8e4667a2cb9b5 + @truncate(usize, offset_u), + if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0, ); } pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: i64, flags: kernel_rwf) usize { - const offset_halves = splitValue64(offset); + const offset_u = @bitCast(u64, offset); return syscall6( .preadv2, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count, - offset_halves[0], - offset_halves[1], + // See comments in preadv + @truncate(usize, offset_u), + if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0, flags, ); } @@ -473,26 +477,28 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize { } pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64) usize { - const offset_halves = splitValueLE64(offset); + const offset_u = @bitCast(u64, offset); return syscall5( .pwritev, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count, - offset_halves[0], - offset_halves[1], + // See comments in preadv + @truncate(usize, offset_u), + if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0, ); } pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64, flags: kernel_rwf) usize { - const offset_halves = splitValue64(offset); + const offset_u = @bitCast(u64, offset); return syscall6( .pwritev2, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count, - offset_halves[0], - offset_halves[1], + // See comments in preadv + @truncate(usize, offset_u), + if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0, flags, ); }