From 8a5b39f734d63c65d4dc07cbf20e2e3b7a41a0b1 Mon Sep 17 00:00:00 2001 From: Vitalii Kravchenko Date: Sun, 2 Oct 2022 07:40:28 +0100 Subject: [PATCH 1/2] Darwin: allow reading/writing files larger than max(i32) --- core/os/os_darwin.odin | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 5c2cf8ec2..9dbb73a25 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -369,27 +369,45 @@ close :: proc(fd: Handle) -> bool { return _unix_close(fd) == 0 } +@(private) +MAX_RW :: 0x7fffffff // The limit on Darwin is max(i32), trying to read/write more than that fails. + write :: proc(fd: Handle, data: []u8) -> (int, Errno) { assert(fd != -1) - if len(data) == 0 { - return 0, 0 - } - bytes_written := _unix_write(fd, raw_data(data), len(data)) - if bytes_written == -1 { - return 0, 1 - } - return bytes_written, 0 + bytes_total := len(data) + bytes_written_total := 0 + + for bytes_written_total < bytes_total { + bytes_to_write := min(bytes_total - bytes_written_total, MAX_RW) + slice := data[bytes_written_total:bytes_written_total + bytes_to_write] + bytes_written := _unix_write(fd, raw_data(slice), bytes_to_write) + if bytes_written == -1 { + return bytes_written_total, 1 + } + bytes_written_total += bytes_written + } + + return bytes_written_total, 0 } read :: proc(fd: Handle, data: []u8) -> (int, Errno) { assert(fd != -1) - bytes_read := _unix_read(fd, raw_data(data), len(data)) - if bytes_read == -1 { - return 0, 1 + bytes_total := len(data) + bytes_read_total := 0 + + for bytes_read_total < bytes_total { + bytes_to_read := min(bytes_total - bytes_read_total, MAX_RW) + slice := data[bytes_read_total:bytes_read_total + bytes_to_read] + bytes_read := _unix_read(fd, raw_data(slice), bytes_to_read) + if bytes_read == -1 { + return bytes_read_total, 1 + } + bytes_read_total += bytes_read } - return bytes_read, 0 + + return bytes_read_total, 0 } seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { From d52a9b61af066deaa29398bb4195418f2817e42c Mon Sep 17 00:00:00 2001 From: Vitalii Kravchenko Date: Sun, 2 Oct 2022 07:47:22 +0100 Subject: [PATCH 2/2] Fix indentation --- core/os/os_darwin.odin | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 9dbb73a25..ac7376752 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -375,18 +375,18 @@ MAX_RW :: 0x7fffffff // The limit on Darwin is max(i32), trying to read/write mo write :: proc(fd: Handle, data: []u8) -> (int, Errno) { assert(fd != -1) - bytes_total := len(data) - bytes_written_total := 0 + bytes_total := len(data) + bytes_written_total := 0 - for bytes_written_total < bytes_total { + for bytes_written_total < bytes_total { bytes_to_write := min(bytes_total - bytes_written_total, MAX_RW) - slice := data[bytes_written_total:bytes_written_total + bytes_to_write] - bytes_written := _unix_write(fd, raw_data(slice), bytes_to_write) - if bytes_written == -1 { - return bytes_written_total, 1 - } - bytes_written_total += bytes_written - } + slice := data[bytes_written_total:bytes_written_total + bytes_to_write] + bytes_written := _unix_write(fd, raw_data(slice), bytes_to_write) + if bytes_written == -1 { + return bytes_written_total, 1 + } + bytes_written_total += bytes_written + } return bytes_written_total, 0 }