Browse Source

Merge pull request #2102 from yay/darwin-read-write

Darwin: allow reading/writing files larger than max(i32)
gingerBill 2 years ago
parent
commit
4c2e86b063
1 changed files with 29 additions and 11 deletions
  1. 29 11
      core/os/os_darwin.odin

+ 29 - 11
core/os/os_darwin.odin

@@ -369,27 +369,45 @@ close :: proc(fd: Handle) -> bool {
 	return _unix_close(fd) == 0
 	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) {
 write :: proc(fd: Handle, data: []u8) -> (int, Errno) {
 	assert(fd != -1)
 	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
+	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, 0
+
+	return bytes_written_total, 0
 }
 }
 
 
 read :: proc(fd: Handle, data: []u8) -> (int, Errno) {
 read :: proc(fd: Handle, data: []u8) -> (int, Errno) {
 	assert(fd != -1)
 	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) {
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {