aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2023-02-15 11:07:42 +0000
committerGitHub <noreply@github.com>2023-02-15 11:07:42 +0000
commitd6407e96366a1d13107dfa457c573c3500a128db (patch)
tree1dbfcfcf9a374f3bf7bd20869940349dea1edf8f
parent48685e8bf15dada1734ad6463fafb7d00c86b2b0 (diff)
parentdf58a00564b6dfcb7dc91cfe390133dc2a6e94d5 (diff)
Merge pull request #2331 from colrdavidson/platform_file_cleanup
make file access a little more normal across platforms
-rw-r--r--core/os/os_darwin.odin72
-rw-r--r--core/os/os_linux.odin34
2 files changed, 71 insertions, 35 deletions
diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin
index 2d8a871c1..e08c9005a 100644
--- a/core/os/os_darwin.odin
+++ b/core/os/os_darwin.odin
@@ -277,8 +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="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 ---
@@ -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, Errno(get_last_error())
+ }
+ return bytes_written, ERROR_NONE
}
read :: proc(fd: Handle, data: []u8) -> (int, Errno) {
- assert(fd != -1)
+ 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, Errno(get_last_error())
+ }
+ 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_total := len(data)
- bytes_read_total := 0
+ bytes_read := _unix_pread(fd, raw_data(data), c.size_t(len(data)), offset)
+ if bytes_read < 0 {
+ return -1, Errno(get_last_error())
+ }
+ return bytes_read, ERROR_NONE
+}
- 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
+write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
+ if len(data) == 0 {
+ return 0, ERROR_NONE
}
- return bytes_read_total, 0
+ bytes_written := _unix_pwrite(fd, raw_data(data), c.size_t(len(data)), offset)
+ if bytes_written < 0 {
+ return -1, Errno(get_last_error())
+ }
+ 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 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 int(bytes_written), ERROR_NONE
+ return bytes_written, ERROR_NONE
}
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {