| ... | ... | @@ -324,7 +324,7 @@ pub const ReadError = error{ |
| 324 | 324 | /// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as |
| 325 | 325 | /// well as stuffing the errno codes into the last `4096` values. This is noted on the `read` man page. |
| 326 | 326 | /// The limit on Darwin is `0x7fffffff`, trying to read more than that returns EINVAL. |
| 327 | | /// For POSIX the limit is `math.maxInt(isize)`. |
| 327 | /// The corresponding POSIX limit is `math.maxInt(isize)`. |
| 328 | 328 | pub fn read(fd: fd_t, buf: []u8) ReadError!usize { |
| 329 | 329 | if (builtin.os.tag == .windows) { |
| 330 | 330 | return windows.ReadFile(fd, buf, null, std.io.default_mode); |
| ... | ... | @@ -447,6 +447,12 @@ pub const PReadError = ReadError || error{Unseekable}; |
| 447 | 447 | /// return error.WouldBlock when EAGAIN is received. |
| 448 | 448 | /// On Windows, if the application has a global event loop enabled, I/O Completion Ports are |
| 449 | 449 | /// used to perform the I/O. `error.WouldBlock` is not possible on Windows. |
| 450 | /// |
| 451 | /// Linux has a limit on how many bytes may be transferred in one `pread` call, which is `0x7ffff000` |
| 452 | /// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as |
| 453 | /// well as stuffing the errno codes into the last `4096` values. This is noted on the `read` man page. |
| 454 | /// The limit on Darwin is `0x7fffffff`, trying to read more than that returns EINVAL. |
| 455 | /// The corresponding POSIX limit is `math.maxInt(isize)`. |
| 450 | 456 | pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize { |
| 451 | 457 | if (builtin.os.tag == .windows) { |
| 452 | 458 | return windows.ReadFile(fd, buf, offset, std.io.default_mode); |
| ... | ... | @@ -478,8 +484,16 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize { |
| 478 | 484 | } |
| 479 | 485 | } |
| 480 | 486 | |
| 487 | // Prevent EINVAL. |
| 488 | const max_count = switch (std.Target.current.os.tag) { |
| 489 | .linux => 0x7ffff000, |
| 490 | .macos, .ios, .watchos, .tvos => math.maxInt(i32), |
| 491 | else => math.maxInt(isize), |
| 492 | }; |
| 493 | const adjusted_len = math.min(max_count, buf.len); |
| 494 | |
| 481 | 495 | while (true) { |
| 482 | | const rc = system.pread(fd, buf.ptr, buf.len, offset); |
| 496 | const rc = system.pread(fd, buf.ptr, adjusted_len, offset); |
| 483 | 497 | switch (errno(rc)) { |
| 484 | 498 | 0 => return @intCast(usize, rc), |
| 485 | 499 | EINTR => continue, |
| ... | ... | @@ -4926,7 +4940,7 @@ fn count_iovec_bytes(iovs: []const iovec_const) usize { |
| 4926 | 4940 | /// |
| 4927 | 4941 | /// Linux has a limit on how many bytes may be transferred in one `sendfile` call, which is `0x7ffff000` |
| 4928 | 4942 | /// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as |
| 4929 | | /// well as stuffing the errno codes into the last `4096` values. This is cited on the `sendfile` man page. |
| 4943 | /// well as stuffing the errno codes into the last `4096` values. This is noted on the `sendfile` man page. |
| 4930 | 4944 | /// The limit on Darwin is `0x7fffffff`, trying to write more than that returns EINVAL. |
| 4931 | 4945 | /// The corresponding POSIX limit on this is `math.maxInt(isize)`. |
| 4932 | 4946 | pub fn sendfile( |