Переглянути джерело

Report `Invalid_Whence` on some `os` platforms

- Move `Seek`-related checks into OS-specific files for granularity.

Platforms:
- Darwin
- FreeBSD
- Haiku
- Linux
- NetBSD
- OpenBSD
Feoramund 1 рік тому
батько
коміт
6aedb2695a

+ 12 - 1
core/os/os_darwin.odin

@@ -777,10 +777,21 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) {
 
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
 	assert(fd != -1)
+	switch whence {
+	case SEEK_SET, SEEK_CUR, SEEK_END:
+		break
+	case:
+		return 0, .Invalid_Whence
+	}
 
 	final_offset := i64(_unix_lseek(fd, int(offset), c.int(whence)))
 	if final_offset == -1 {
-		return 0, get_last_error()
+		errno := get_last_error()
+		switch errno {
+		case .EINVAL:
+			return 0, .Invalid_Offset
+		}
+		return 0, errno
 	}
 	return final_offset, nil
 }

+ 13 - 1
core/os/os_freebsd.odin

@@ -505,9 +505,21 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error)
 }
 
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
+	switch whence {
+	case SEEK_SET, SEEK_CUR, SEEK_END:
+		break
+	case:
+		return 0, .Invalid_Whence
+	}
 	res := _unix_seek(fd, offset, c.int(whence))
 	if res == -1 {
-		return -1, get_last_error()
+		errno := get_last_error()
+		switch errno {
+		case .EINVAL:
+			return 0, .Invalid_Offset
+		case:
+			return 0, errno
+		}
 	}
 	return res, nil
 }

+ 12 - 1
core/os/os_haiku.odin

@@ -284,9 +284,20 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error)
 }
 
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
+	switch whence {
+	case SEEK_SET, SEEK_CUR, SEEK_END:
+		break
+	case:
+		return 0, .Invalid_Whence
+	}
 	res := _unix_seek(fd, offset, c.int(whence))
 	if res == -1 {
-		return -1, get_last_error()
+		errno := get_last_error()
+		switch errno {
+		case .BAD_VALUE:
+			return 0, .Invalid_Offset
+		}
+		return 0, errno
 	}
 	return res, nil
 }

+ 12 - 1
core/os/os_linux.odin

@@ -653,9 +653,20 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) {
 }
 
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
+	switch whence {
+	case SEEK_SET, SEEK_CUR, SEEK_END:
+		break
+	case:
+		return 0, .Invalid_Whence
+	}
 	res := unix.sys_lseek(int(fd), offset, whence)
 	if res < 0 {
-		return -1, _get_errno(int(res))
+		errno := _get_errno(int(res))
+		switch errno {
+		case .EINVAL:
+			return 0, .Invalid_Offset
+		}
+		return 0, errno
 	}
 	return i64(res), nil
 }

+ 12 - 1
core/os/os_netbsd.odin

@@ -569,9 +569,20 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error)
 }
 
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
+	switch whence {
+	case SEEK_SET, SEEK_CUR, SEEK_END:
+		break
+	case:
+		return 0, .Invalid_Whence
+	}
 	res := _unix_seek(fd, offset, c.int(whence))
 	if res == -1 {
-		return -1, get_last_error()
+		errno := get_last_error()
+		switch errno {
+		case .EINVAL:
+			return 0, .Invalid_Offset
+		}
+		return 0, errno
 	}
 	return res, nil
 }

+ 12 - 1
core/os/os_openbsd.odin

@@ -497,9 +497,20 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error)
 }
 
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
+	switch whence {
+	case SEEK_SET, SEEK_CUR, SEEK_END:
+		break
+	case:
+		return 0, .Invalid_Whence
+	}
 	res := _unix_seek(fd, offset, c.int(whence))
 	if res == -1 {
-		return -1, get_last_error()
+		errno := get_last_error()
+		switch errno {
+		case .EINVAL:
+			return 0, .Invalid_Offset
+		}
+		return 0, errno
 	}
 	return res, nil
 }

+ 0 - 8
core/os/stream.odin

@@ -47,14 +47,6 @@ _file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte,
 		}
 	case .Seek:
 		n, os_err = seek(fd, offset, int(whence))
-		if os_err != nil {
-			switch whence {
-			case .Start, .Current, .End:
-				return 0, .Invalid_Offset
-			case:
-				return 0, .Invalid_Whence
-			}
-		}
 	case .Size:
 		n, os_err = file_size(fd)
 	case .Destroy: