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 {...@@ -440,26 +440,30 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
440}440}
441441
442pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: i64) usize {442pub 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);
444 return syscall5(444 return syscall5(
445 .preadv,445 .preadv,
446 @bitCast(usize, @as(isize, fd)),446 @bitCast(usize, @as(isize, fd)),
447 @ptrToInt(iov),447 @ptrToInt(iov),
448 count,448 count,
449 offset_halves[0],449 // Kernel expects the offset is splitted into largest natural word-size.
450 offset_halves[1],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,
451 );454 );
452}455}
453456
454pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: i64, flags: kernel_rwf) usize {457pub 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);
456 return syscall6(459 return syscall6(
457 .preadv2,460 .preadv2,
458 @bitCast(usize, @as(isize, fd)),461 @bitCast(usize, @as(isize, fd)),
459 @ptrToInt(iov),462 @ptrToInt(iov),
460 count,463 count,
461 offset_halves[0],464 // See comments in preadv
462 offset_halves[1],465 @truncate(usize, offset_u),
466 if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0,
463 flags,467 flags,
464 );468 );
465}469}
...@@ -473,26 +477,28 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {...@@ -473,26 +477,28 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {
473}477}
474478
475pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64) usize {479pub 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);
477 return syscall5(481 return syscall5(
478 .pwritev,482 .pwritev,
479 @bitCast(usize, @as(isize, fd)),483 @bitCast(usize, @as(isize, fd)),
480 @ptrToInt(iov),484 @ptrToInt(iov),
481 count,485 count,
482 offset_halves[0],486 // See comments in preadv
483 offset_halves[1],487 @truncate(usize, offset_u),
488 if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0,
484 );489 );
485}490}
486491
487pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64, flags: kernel_rwf) usize {492pub 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);
489 return syscall6(494 return syscall6(
490 .pwritev2,495 .pwritev2,
491 @bitCast(usize, @as(isize, fd)),496 @bitCast(usize, @as(isize, fd)),
492 @ptrToInt(iov),497 @ptrToInt(iov),
493 count,498 count,
494 offset_halves[0],499 // See comments in preadv
495 offset_halves[1],500 @truncate(usize, offset_u),
501 if (usize_bits < 64) @truncate(usize, offset_u >> 32) else 0,
496 flags,502 flags,
497 );503 );
498}504}