From 8bb58fb4286ad03a243e32e31d67dd2bb5c117ef Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 11 May 2021 15:49:53 +0200 Subject: [PATCH] std: Fix offset param splitting for preadv/pwritev The kernel interface expects the offset as a low+high pair even on BE systems. --- lib/std/os/linux.zig | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index d5e25f2ab7..fbb44ba7bd 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -59,6 +59,20 @@ const require_aligned_register_pair = std.Target.current.cpu.arch.isThumb(); // Split a 64bit value into a {LSB,MSB} pair. +// The LE/BE variants specify the endianness to assume. +fn splitValueLE64(val: i64) [2]u32 { + const u = @bitCast(u64, val); + return [2]u32{ + @truncate(u32, u), + @truncate(u32, u >> 32), + }; +} +fn splitValueBE64(val: i64) [2]u32 { + return [2]u32{ + @truncate(u32, u >> 32), + @truncate(u32, u), + }; +} fn splitValue64(val: i64) [2]u32 { const u = @bitCast(u64, val); switch (builtin.endian) { @@ -310,7 +324,7 @@ 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 = splitValue64(offset); + const offset_halves = splitValueLE64(offset); return syscall5( .preadv, @bitCast(usize, @as(isize, fd)), @@ -343,7 +357,7 @@ 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 = splitValue64(offset); + const offset_halves = splitValueLE64(offset); return syscall5( .pwritev, @bitCast(usize, @as(isize, fd)),