From 04b1023988a350c12c252506ca1cde2034a86492 Mon Sep 17 00:00:00 2001 From: Colin Davidson Date: Tue, 14 Feb 2023 18:34:03 -0800 Subject: [PATCH 1/3] make file access a little more normal across platforms --- core/os/os_darwin.odin | 72 +++++++++++++++++++++++------------------- core/os/os_linux.odin | 34 ++++++++++++++++++-- 2 files changed, 71 insertions(+), 35 deletions(-) diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 2d8a871c1..3556e833a 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -279,6 +279,8 @@ foreign libc { @(link_name="close") _unix_close :: proc(handle: Handle) -> c.int --- @(link_name="read") _unix_read :: proc(handle: Handle, buffer: rawptr, count: int) -> int --- @(link_name="write") _unix_write :: proc(handle: Handle, buffer: rawptr, count: int) -> int --- + @(link_name="pread") _unix_pread :: proc(handle: Handle, buffer: rawptr, count: int, offset: i64) -> int --- + @(link_name="pwrite") _unix_pwrite :: proc(handle: Handle, buffer: rawptr, count: int, offset: i64) -> int --- @(link_name="lseek") _unix_lseek :: proc(fs: Handle, offset: int, whence: int) -> int --- @(link_name="gettid") _unix_gettid :: proc() -> u64 --- @(link_name="getpagesize") _unix_getpagesize :: proc() -> i32 --- @@ -385,45 +387,51 @@ close :: proc(fd: Handle) -> bool { @(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) - - 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 +write :: proc(fd: Handle, data: []byte) -> (int, Errno) { + if len(data) == 0 { + return 0, ERROR_NONE } - return bytes_written_total, 0 + bytes_written := _unix_write(fd, raw_data(data), c.size_t(len(data))) + if bytes_written < 0 { + return -1, _get_errno(bytes_written) + } + return bytes_written, ERROR_NONE } read :: proc(fd: Handle, data: []u8) -> (int, Errno) { - assert(fd != -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 - } - if bytes_read == 0 { - break - } - bytes_read_total += bytes_read + if len(data) == 0 { + return 0, ERROR_NONE } - return bytes_read_total, 0 + bytes_read := _unix_read(fd, raw_data(slice), c.size_t(len(data))) + if bytes_read < 0 { + return -1, _get_errno(bytes_read) + } + return bytes_read, ERROR_NONE +} +read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) { + if len(data) == 0 { + return 0, ERROR_NONE + } + + bytes_read := _unix_pread(int(fd), raw_data(data), c.size_t(len(data)), offset) + if bytes_read < 0 { + return -1, _get_errno(bytes_read) + } + return bytes_read, ERROR_NONE +} + +write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) { + if len(data) == 0 { + return 0, ERROR_NONE + } + + bytes_written := _unix_pwrite(int(fd), raw_data(data), c.size_t(len(data)), offset) + if bytes_written < 0 { + return -1, _get_errno(bytes_written) + } + return bytes_written, ERROR_NONE } seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 1a66f7704..e4865a2ff 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -476,7 +476,11 @@ close :: proc(fd: Handle) -> Errno { } read :: proc(fd: Handle, data: []byte) -> (int, Errno) { - bytes_read := _unix_read(fd, &data[0], c.size_t(len(data))) + if len(data) == 0 { + return 0, ERROR_NONE + } + + bytes_read := _unix_read(fd, raw_data(data), c.size_t(len(data))) if bytes_read < 0 { return -1, _get_errno(bytes_read) } @@ -487,11 +491,35 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) { if len(data) == 0 { return 0, ERROR_NONE } - bytes_written := _unix_write(fd, &data[0], uint(len(data))) + + bytes_written := _unix_write(fd, raw_data(data), uint(len(data))) if bytes_written < 0 { return -1, _get_errno(bytes_written) } - return int(bytes_written), ERROR_NONE + return bytes_written, ERROR_NONE +} +read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) { + if len(data) == 0 { + return 0, ERROR_NONE + } + + bytes_read := unix.sys_pread(int(fd), raw_data(data), c.size_t(len(data)), offset) + if bytes_read < 0 { + return -1, _get_errno(bytes_read) + } + return bytes_read, ERROR_NONE +} + +write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) { + if len(data) == 0 { + return 0, ERROR_NONE + } + + bytes_written := unix.sys_pwrite(int(fd), raw_data(data), uint(len(data)), offset) + if bytes_written < 0 { + return -1, _get_errno(bytes_written) + } + return bytes_written, ERROR_NONE } seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { From d546677ae7ee1aca1dd5801f93685ae22087e92e Mon Sep 17 00:00:00 2001 From: Colin Davidson Date: Tue, 14 Feb 2023 18:39:09 -0800 Subject: [PATCH 2/3] fix typo --- core/os/os_darwin.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 3556e833a..fc2cb8e1a 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -404,7 +404,7 @@ read :: proc(fd: Handle, data: []u8) -> (int, Errno) { return 0, ERROR_NONE } - bytes_read := _unix_read(fd, raw_data(slice), c.size_t(len(data))) + bytes_read := _unix_read(fd, raw_data(data), c.size_t(len(data))) if bytes_read < 0 { return -1, _get_errno(bytes_read) } From df58a00564b6dfcb7dc91cfe390133dc2a6e94d5 Mon Sep 17 00:00:00 2001 From: Colin Davidson Date: Tue, 14 Feb 2023 18:43:48 -0800 Subject: [PATCH 3/3] fix errno/signatures --- 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 fc2cb8e1a..e08c9005a 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -277,10 +277,10 @@ foreign libc { @(link_name="open") _unix_open :: proc(path: cstring, flags: i32, mode: u16) -> Handle --- @(link_name="close") _unix_close :: proc(handle: Handle) -> c.int --- - @(link_name="read") _unix_read :: proc(handle: Handle, buffer: rawptr, count: int) -> int --- - @(link_name="write") _unix_write :: proc(handle: Handle, buffer: rawptr, count: int) -> int --- - @(link_name="pread") _unix_pread :: proc(handle: Handle, buffer: rawptr, count: int, offset: i64) -> int --- - @(link_name="pwrite") _unix_pwrite :: proc(handle: Handle, buffer: rawptr, count: int, offset: i64) -> int --- + @(link_name="read") _unix_read :: proc(handle: Handle, buffer: rawptr, count: c.size_t) -> int --- + @(link_name="write") _unix_write :: proc(handle: Handle, buffer: rawptr, count: c.size_t) -> int --- + @(link_name="pread") _unix_pread :: proc(handle: Handle, buffer: rawptr, count: c.size_t, offset: i64) -> int --- + @(link_name="pwrite") _unix_pwrite :: proc(handle: Handle, buffer: rawptr, count: c.size_t, offset: i64) -> int --- @(link_name="lseek") _unix_lseek :: proc(fs: Handle, offset: int, whence: int) -> int --- @(link_name="gettid") _unix_gettid :: proc() -> u64 --- @(link_name="getpagesize") _unix_getpagesize :: proc() -> i32 --- @@ -394,7 +394,7 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) { bytes_written := _unix_write(fd, raw_data(data), c.size_t(len(data))) if bytes_written < 0 { - return -1, _get_errno(bytes_written) + return -1, Errno(get_last_error()) } return bytes_written, ERROR_NONE } @@ -406,7 +406,7 @@ read :: proc(fd: Handle, data: []u8) -> (int, Errno) { bytes_read := _unix_read(fd, raw_data(data), c.size_t(len(data))) if bytes_read < 0 { - return -1, _get_errno(bytes_read) + return -1, Errno(get_last_error()) } return bytes_read, ERROR_NONE } @@ -415,9 +415,9 @@ read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) { return 0, ERROR_NONE } - bytes_read := _unix_pread(int(fd), raw_data(data), c.size_t(len(data)), offset) + bytes_read := _unix_pread(fd, raw_data(data), c.size_t(len(data)), offset) if bytes_read < 0 { - return -1, _get_errno(bytes_read) + return -1, Errno(get_last_error()) } return bytes_read, ERROR_NONE } @@ -427,9 +427,9 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) { return 0, ERROR_NONE } - bytes_written := _unix_pwrite(int(fd), raw_data(data), c.size_t(len(data)), offset) + bytes_written := _unix_pwrite(fd, raw_data(data), c.size_t(len(data)), offset) if bytes_written < 0 { - return -1, _get_errno(bytes_written) + return -1, Errno(get_last_error()) } return bytes_written, ERROR_NONE }