From 6aedb2695a5094aac15758ef79c3af84be27df38 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sun, 25 Aug 2024 20:53:04 -0400 Subject: [PATCH] Report `Invalid_Whence` on some `os` platforms - Move `Seek`-related checks into OS-specific files for granularity. Platforms: - Darwin - FreeBSD - Haiku - Linux - NetBSD - OpenBSD --- core/os/os_darwin.odin | 13 ++++++++++++- core/os/os_freebsd.odin | 14 +++++++++++++- core/os/os_haiku.odin | 13 ++++++++++++- core/os/os_linux.odin | 13 ++++++++++++- core/os/os_netbsd.odin | 13 ++++++++++++- core/os/os_openbsd.odin | 13 ++++++++++++- core/os/stream.odin | 8 -------- 7 files changed, 73 insertions(+), 14 deletions(-) diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 1253e9ae6..2bb6c0c59 100644 --- a/core/os/os_darwin.odin +++ b/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 } diff --git a/core/os/os_freebsd.odin b/core/os/os_freebsd.odin index affff6910..c05a06129 100644 --- a/core/os/os_freebsd.odin +++ b/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 } diff --git a/core/os/os_haiku.odin b/core/os/os_haiku.odin index 08bd4f832..0d2c334be 100644 --- a/core/os/os_haiku.odin +++ b/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 } diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index ba200a308..9132edbfe 100644 --- a/core/os/os_linux.odin +++ b/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 } diff --git a/core/os/os_netbsd.odin b/core/os/os_netbsd.odin index d84be41f7..a56c0b784 100644 --- a/core/os/os_netbsd.odin +++ b/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 } diff --git a/core/os/os_openbsd.odin b/core/os/os_openbsd.odin index d30511d9c..aff78dc60 100644 --- a/core/os/os_openbsd.odin +++ b/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 } diff --git a/core/os/stream.odin b/core/os/stream.odin index c849319ae..ad8c2461c 100644 --- a/core/os/stream.odin +++ b/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: