authorgravatar for wei.tan@intel.comTw <wei.tan@intel.com> 2022-01-29 17:44:13+08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-14 12:48:55-07:00
logf9af406341faa2b649e0578d82ae658b38e31a89
tree52c1ea6b61202814a5004a51cd384b3c14946d23
parent8bf14231b23fd68b8ce291de4ee563bc30fc4e15

Fix preadv/pwritev bug on 64bit platform

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

1 files changed, 18 insertions(+), 12 deletions(-)

lib/std/os/linux.zig+18-12
......@@ -440,26 +440,30 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
440440}
441441
442442pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: i64) usize {
443 const offset_halves = splitValueLE64(offset);
443 const offset_u = @bitCast(u64, offset);
444444 return syscall5(
445445 .preadv,
446446 @bitCast(usize, @as(isize, fd)),
447447 @ptrToInt(iov),
448448 count,
449 offset_halves[0],
450 offset_halves[1],
449 // Kernel expects the offset is splitted into largest natural word-size.
450 // See following link for detail:
451 // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=601cc11d054ae4b5e9b5babec3d8e4667a2cb9b5
452 @truncate(usize, offset_u),
453 if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0,
451454 );
452455}
453456
454457pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: i64, flags: kernel_rwf) usize {
455 const offset_halves = splitValue64(offset);
458 const offset_u = @bitCast(u64, offset);
456459 return syscall6(
457460 .preadv2,
458461 @bitCast(usize, @as(isize, fd)),
459462 @ptrToInt(iov),
460463 count,
461 offset_halves[0],
462 offset_halves[1],
464 // See comments in preadv
465 @truncate(usize, offset_u),
466 if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0,
463467 flags,
464468 );
465469}
......@@ -473,26 +477,28 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {
473477}
474478
475479pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64) usize {
476 const offset_halves = splitValueLE64(offset);
480 const offset_u = @bitCast(u64, offset);
477481 return syscall5(
478482 .pwritev,
479483 @bitCast(usize, @as(isize, fd)),
480484 @ptrToInt(iov),
481485 count,
482 offset_halves[0],
483 offset_halves[1],
486 // See comments in preadv
487 @truncate(usize, offset_u),
488 if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0,
484489 );
485490}
486491
487492pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64, flags: kernel_rwf) usize {
488 const offset_halves = splitValue64(offset);
493 const offset_u = @bitCast(u64, offset);
489494 return syscall6(
490495 .pwritev2,
491496 @bitCast(usize, @as(isize, fd)),
492497 @ptrToInt(iov),
493498 count,
494 offset_halves[0],
495 offset_halves[1],
499 // See comments in preadv
500 @truncate(usize, offset_u),
501 if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0,
496502 flags,
497503 );
498504}