aboutsummaryrefslogtreecommitdiff
path: root/core/os
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2024-08-04 11:44:45 +0100
committergingerBill <bill@gingerbill.org>2024-08-04 11:44:45 +0100
commitdef2e2e27112e4cc745afaa89a03857e01c5aabd (patch)
treee8a7deddf9f7c3cef5f685ab9b8c5ac3e9a561a0 /core/os
parent28666414bc767c99c5d157f64e41b18b06082e42 (diff)
Try to map to `General_Error` where possible
Diffstat (limited to 'core/os')
-rw-r--r--core/os/dir_unix.odin1
-rw-r--r--core/os/dir_windows.odin1
-rw-r--r--core/os/env_windows.odin3
-rw-r--r--core/os/file_windows.odin5
-rw-r--r--core/os/os.odin36
-rw-r--r--core/os/os2/errors.odin3
-rw-r--r--core/os/os_linux.odin13
-rw-r--r--core/os/os_windows.odin48
8 files changed, 103 insertions, 7 deletions
diff --git a/core/os/dir_unix.odin b/core/os/dir_unix.odin
index 240e6ed8d..727dd1319 100644
--- a/core/os/dir_unix.odin
+++ b/core/os/dir_unix.odin
@@ -3,6 +3,7 @@ package os
import "core:strings"
+@(require_results)
read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) {
dirp := _fdopendir(fd) or_return
defer _closedir(dirp)
diff --git a/core/os/dir_windows.odin b/core/os/dir_windows.odin
index 1df1c2b9e..c96ce53f5 100644
--- a/core/os/dir_windows.odin
+++ b/core/os/dir_windows.odin
@@ -4,6 +4,7 @@ import win32 "core:sys/windows"
import "core:strings"
import "base:runtime"
+@(require_results)
read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) {
find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW) -> (fi: File_Info) {
// Ignore "." and ".."
diff --git a/core/os/env_windows.odin b/core/os/env_windows.odin
index 04ce98638..a73687a3c 100644
--- a/core/os/env_windows.odin
+++ b/core/os/env_windows.odin
@@ -7,6 +7,7 @@ import "base:runtime"
// If the variable is found in the environment the value (which can be empty) is returned and the boolean is true
// Otherwise the returned value will be empty and the boolean will be false
// NOTE: the value will be allocated with the supplied allocator
+@(require_results)
lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) {
if key == "" {
return
@@ -33,6 +34,7 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin
// It returns the value, which will be empty if the variable is not present
// To distinguish between an empty value and an unset value, use lookup_env
// NOTE: the value will be allocated with the supplied allocator
+@(require_results)
get_env :: proc(key: string, allocator := context.allocator) -> (value: string) {
value, _ = lookup_env(key, allocator)
return
@@ -60,6 +62,7 @@ unset_env :: proc(key: string) -> Errno {
// environ returns a copy of strings representing the environment, in the form "key=value"
// NOTE: the slice of strings and the strings with be allocated using the supplied allocator
+@(require_results)
environ :: proc(allocator := context.allocator) -> []string {
envs := ([^]win32.WCHAR)(win32.GetEnvironmentStringsW())
if envs == nil {
diff --git a/core/os/file_windows.odin b/core/os/file_windows.odin
index 8bfd9276d..7831aa3e6 100644
--- a/core/os/file_windows.odin
+++ b/core/os/file_windows.odin
@@ -11,7 +11,7 @@ is_path_separator :: proc(c: byte) -> bool {
open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
if len(path) == 0 {
- return INVALID_HANDLE, ERROR_FILE_NOT_FOUND
+ return INVALID_HANDLE, General_Error.Not_Exist
}
access: u32
@@ -55,8 +55,7 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errn
return handle, nil
}
- err := get_last_error()
- return INVALID_HANDLE, err
+ return INVALID_HANDLE, get_last_error()
}
close :: proc(fd: Handle) -> Errno {
diff --git a/core/os/os.odin b/core/os/os.odin
index d8c0ef658..3db3c5bd7 100644
--- a/core/os/os.odin
+++ b/core/os/os.odin
@@ -19,17 +19,51 @@ Platform_Error :: _Platform_Error
#assert(size_of(Platform_Error) <= 4)
#assert(intrinsics.type_has_nil(Platform_Error))
+General_Error :: enum u32 {
+ None,
+
+ Permission_Denied,
+ Exist,
+ Not_Exist,
+ Closed,
+
+ Timeout,
+
+ Broken_Pipe,
+
+ // Indicates that an attempt to retrieve a file's size was made, but the
+ // file doesn't have a size.
+ No_Size,
+
+ Invalid_File,
+ Invalid_Dir,
+ Invalid_Path,
+ Invalid_Callback,
+
+ Pattern_Has_Separator,
+
+ Unsupported,
+}
+
+
Errno :: Error // alias for legacy use
Error :: union #shared_nil {
+ General_Error,
io.Error,
runtime.Allocator_Error,
Platform_Error,
}
-#assert(size_of(Error) <= 8)
+#assert(size_of(Error) == 8)
ERROR_NONE :: Error{}
+@(require_results)
+is_platform_error :: proc(ferr: Error) -> (err: i32, ok: bool) {
+ v := ferr.(Platform_Error) or_else {}
+ return i32(v), i32(v) != 0
+}
+
write_string :: proc(fd: Handle, str: string) -> (int, Errno) {
return write(fd, transmute([]byte)str)
}
diff --git a/core/os/os2/errors.odin b/core/os/os2/errors.odin
index 2b9b3528e..bc51bb1e8 100644
--- a/core/os/os2/errors.odin
+++ b/core/os/os2/errors.odin
@@ -42,13 +42,14 @@ Error :: union #shared_nil {
ERROR_NONE :: Error{}
-
+@(require_results)
is_platform_error :: proc(ferr: Error) -> (err: i32, ok: bool) {
v := ferr.(Platform_Error) or_else {}
return i32(v), i32(v) != 0
}
+@(require_results)
error_string :: proc(ferr: Error) -> string {
if ferr == nil {
return ""
diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin
index 3d24e2258..4d5b13930 100644
--- a/core/os/os_linux.odin
+++ b/core/os/os_linux.odin
@@ -521,7 +521,18 @@ _get_errno :: proc(res: int) -> Errno {
// get errno from libc
get_last_error :: proc "contextless" () -> Error {
- return Platform_Error(__errno_location()^)
+ err := Platform_Error(__errno_location()^)
+ #partial switch err {
+ case .NONE:
+ return nil
+ case .EPERM:
+ return .Permission_Denied
+ case .EEXIST:
+ return .Exist
+ case .ENOENT:
+ return .Not_Exist
+ }
+ return err
}
personality :: proc(persona: u64) -> (Errno) {
diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin
index afba3c3b4..99c28d880 100644
--- a/core/os/os_windows.odin
+++ b/core/os/os_windows.odin
@@ -64,7 +64,53 @@ ERROR_NEGATIVE_OFFSET :: _Platform_Error(1<<29 + 2)
args := _alloc_command_line_arguments()
get_last_error :: proc "contextless" () -> Error {
- return Platform_Error(win32.GetLastError())
+ err := win32.GetLastError()
+ if err == 0 {
+ return nil
+ }
+ switch err {
+ case win32.ERROR_ACCESS_DENIED, win32.ERROR_SHARING_VIOLATION:
+ return .Permission_Denied
+
+ case win32.ERROR_FILE_EXISTS, win32.ERROR_ALREADY_EXISTS:
+ return .Exist
+
+ case win32.ERROR_FILE_NOT_FOUND, win32.ERROR_PATH_NOT_FOUND:
+ return .Not_Exist
+
+ case win32.ERROR_NO_DATA:
+ return .Closed
+
+ case win32.ERROR_TIMEOUT, win32.WAIT_TIMEOUT:
+ return .Timeout
+
+ case win32.ERROR_NOT_SUPPORTED:
+ return .Unsupported
+
+ case win32.ERROR_HANDLE_EOF:
+ return .EOF
+
+ case win32.ERROR_INVALID_HANDLE:
+ return .Invalid_File
+
+ case
+ win32.ERROR_BAD_ARGUMENTS,
+ win32.ERROR_INVALID_PARAMETER,
+ win32.ERROR_NOT_ENOUGH_MEMORY,
+ win32.ERROR_NO_MORE_FILES,
+ win32.ERROR_LOCK_VIOLATION,
+ win32.ERROR_BROKEN_PIPE,
+ win32.ERROR_CALL_NOT_IMPLEMENTED,
+ win32.ERROR_INSUFFICIENT_BUFFER,
+ win32.ERROR_INVALID_NAME,
+ win32.ERROR_LOCK_FAILED,
+ win32.ERROR_ENVVAR_NOT_FOUND,
+ win32.ERROR_OPERATION_ABORTED,
+ win32.ERROR_IO_PENDING,
+ win32.ERROR_NO_UNICODE_TRANSLATION:
+ // fallthrough
+ }
+ return Platform_Error(err)
}