From b3bbb00f1ac9cc3db242c3af9690f6beedf046e8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 28 Feb 2025 13:43:50 +0000 Subject: [PATCH] Add `Error` as part of the return values of `os2.environ` --- core/os/os2/env.odin | 2 +- core/os/os2/env_linux.odin | 18 +++++++++++++----- core/os/os2/env_posix.odin | 18 +++++++++--------- core/os/os2/env_wasi.odin | 27 ++++++++------------------- core/os/os2/env_windows.odin | 20 ++++++++++++++------ core/os/os2/process_windows.odin | 2 +- 6 files changed, 46 insertions(+), 41 deletions(-) diff --git a/core/os/os2/env.odin b/core/os/os2/env.odin index c8d39b270..ccc857ad8 100644 --- a/core/os/os2/env.odin +++ b/core/os/os2/env.odin @@ -41,7 +41,7 @@ clear_env :: proc() { // 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: runtime.Allocator) -> []string { +environ :: proc(allocator: runtime.Allocator) -> ([]string, Error) { return _environ(allocator) } diff --git a/core/os/os2/env_linux.odin b/core/os/os2/env_linux.odin index e0ef06010..efa308220 100644 --- a/core/os/os2/env_linux.odin +++ b/core/os/os2/env_linux.odin @@ -149,18 +149,26 @@ _clear_env :: proc() { _org_env_end = ~uintptr(0) } -_environ :: proc(allocator: runtime.Allocator) -> []string { +_environ :: proc(allocator: runtime.Allocator) -> (environ: []string, err: Error) { if _org_env_begin == 0 { _build_env() } - env := make([]string, len(_env), allocator) + env := make([dynamic]string, 0, len(_env), allocator) or_return + defer if err != nil { + for e in env { + delete(e, allocator) + } + delete(env) + } sync.mutex_lock(&_env_mutex) defer sync.mutex_unlock(&_env_mutex) - for entry, i in _env { - env[i], _ = clone_string(entry, allocator) + for entry in _env { + s := clone_string(entry, allocator) or_return + append(&env, s) } - return env + environ = env[:] + return } // The entire environment is stored as 0 terminated strings, diff --git a/core/os/os2/env_posix.odin b/core/os/os2/env_posix.odin index e2080485d..a84986864 100644 --- a/core/os/os2/env_posix.odin +++ b/core/os/os2/env_posix.odin @@ -54,23 +54,23 @@ _clear_env :: proc() { } } -_environ :: proc(allocator: runtime.Allocator) -> (environ: []string) { +_environ :: proc(allocator: runtime.Allocator) -> (environ: []string, err: Error) { n := 0 for entry := posix.environ[0]; entry != nil; n, entry = n+1, posix.environ[n] {} - err: runtime.Allocator_Error - if environ, err = make([]string, n, allocator); err != nil { - // NOTE(laytan): is the environment empty or did allocation fail, how does the user know? - return + r := make([dynamic]string, 0, n, allocator) or_return + defer if err != nil { + for e in r { + delete(e, allocator) + } + delete(r) } for i, entry := 0, posix.environ[0]; entry != nil; i, entry = i+1, posix.environ[i] { - if environ[i], err = strings.clone(string(entry), allocator); err != nil { - // NOTE(laytan): is the entire environment returned or did allocation fail, how does the user know? - return - } + append(&r, strings.clone(string(entry), allocator) or_return) } + environ = r[:] return } diff --git a/core/os/os2/env_wasi.odin b/core/os/os2/env_wasi.odin index 8bf4eff38..c43c7c1ec 100644 --- a/core/os/os2/env_wasi.odin +++ b/core/os/os2/env_wasi.odin @@ -153,34 +153,23 @@ _clear_env :: proc() { } @(require_results) -_environ :: proc(allocator: runtime.Allocator) -> []string { - if err := build_env(); err != nil { - return nil - } +_environ :: proc(allocator: runtime.Allocator) -> (environ: []string, err: Error) { + build_env() or_return sync.shared_guard(&g_env_mutex) - envs, alloc_err := make([]string, len(g_env), allocator) - if alloc_err != nil { - return nil - } - - defer if alloc_err != nil { + envs := make([dynamic]string, 0, len(g_env), allocator) or_return + defer if err != nil { for env in envs { delete(env, allocator) } - delete(envs, allocator) + delete(envs) } - i: int for k, v in g_env { - defer i += 1 - - envs[i], alloc_err = concatenate({k, "=", v}, allocator) - if alloc_err != nil { - return nil - } + append(&envs, concatenate({k, "=", v}, allocator) or_return) } - return envs + environ = envs[:] + return } diff --git a/core/os/os2/env_windows.odin b/core/os/os2/env_windows.odin index a1e8c969d..1919657ce 100644 --- a/core/os/os2/env_windows.odin +++ b/core/os/os2/env_windows.odin @@ -52,7 +52,7 @@ _unset_env :: proc(key: string) -> bool { _clear_env :: proc() { TEMP_ALLOCATOR_GUARD() - envs := environ(temp_allocator()) + envs, _ := environ(temp_allocator()) for env in envs { for j in 1..