Add Error as part of the return values of os2.environ

This commit is contained in:
gingerBill
2025-02-28 13:43:50 +00:00
parent 94152ca701
commit b3bbb00f1a
6 changed files with 46 additions and 41 deletions
+1 -1
View File
@@ -41,7 +41,7 @@ clear_env :: proc() {
// environ returns a copy of strings representing the environment, in the form "key=value" // 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 // NOTE: the slice of strings and the strings with be allocated using the supplied allocator
@(require_results) @(require_results)
environ :: proc(allocator: runtime.Allocator) -> []string { environ :: proc(allocator: runtime.Allocator) -> ([]string, Error) {
return _environ(allocator) return _environ(allocator)
} }
+13 -5
View File
@@ -149,18 +149,26 @@ _clear_env :: proc() {
_org_env_end = ~uintptr(0) _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 { if _org_env_begin == 0 {
_build_env() _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) sync.mutex_lock(&_env_mutex)
defer sync.mutex_unlock(&_env_mutex) defer sync.mutex_unlock(&_env_mutex)
for entry, i in _env { for entry in _env {
env[i], _ = clone_string(entry, allocator) s := clone_string(entry, allocator) or_return
append(&env, s)
} }
return env environ = env[:]
return
} }
// The entire environment is stored as 0 terminated strings, // The entire environment is stored as 0 terminated strings,
+9 -9
View File
@@ -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 n := 0
for entry := posix.environ[0]; entry != nil; n, entry = n+1, posix.environ[n] {} for entry := posix.environ[0]; entry != nil; n, entry = n+1, posix.environ[n] {}
err: runtime.Allocator_Error r := make([dynamic]string, 0, n, allocator) or_return
if environ, err = make([]string, n, allocator); err != nil { defer if err != nil {
// NOTE(laytan): is the environment empty or did allocation fail, how does the user know? for e in r {
return delete(e, allocator)
}
delete(r)
} }
for i, entry := 0, posix.environ[0]; entry != nil; i, entry = i+1, posix.environ[i] { 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 { append(&r, strings.clone(string(entry), allocator) or_return)
// NOTE(laytan): is the entire environment returned or did allocation fail, how does the user know?
return
}
} }
environ = r[:]
return return
} }
+8 -19
View File
@@ -153,34 +153,23 @@ _clear_env :: proc() {
} }
@(require_results) @(require_results)
_environ :: proc(allocator: runtime.Allocator) -> []string { _environ :: proc(allocator: runtime.Allocator) -> (environ: []string, err: Error) {
if err := build_env(); err != nil { build_env() or_return
return nil
}
sync.shared_guard(&g_env_mutex) sync.shared_guard(&g_env_mutex)
envs, alloc_err := make([]string, len(g_env), allocator) envs := make([dynamic]string, 0, len(g_env), allocator) or_return
if alloc_err != nil { defer if err != nil {
return nil
}
defer if alloc_err != nil {
for env in envs { for env in envs {
delete(env, allocator) delete(env, allocator)
} }
delete(envs, allocator) delete(envs)
} }
i: int
for k, v in g_env { for k, v in g_env {
defer i += 1 append(&envs, concatenate({k, "=", v}, allocator) or_return)
envs[i], alloc_err = concatenate({k, "=", v}, allocator)
if alloc_err != nil {
return nil
}
} }
return envs environ = envs[:]
return
} }
+14 -6
View File
@@ -52,7 +52,7 @@ _unset_env :: proc(key: string) -> bool {
_clear_env :: proc() { _clear_env :: proc() {
TEMP_ALLOCATOR_GUARD() TEMP_ALLOCATOR_GUARD()
envs := environ(temp_allocator()) envs, _ := environ(temp_allocator())
for env in envs { for env in envs {
for j in 1..<len(env) { for j in 1..<len(env) {
if env[j] == '=' { if env[j] == '=' {
@@ -63,10 +63,10 @@ _clear_env :: proc() {
} }
} }
_environ :: proc(allocator: runtime.Allocator) -> []string { _environ :: proc(allocator: runtime.Allocator) -> (environ: []string, err: Error) {
envs := win32.GetEnvironmentStringsW() envs := win32.GetEnvironmentStringsW()
if envs == nil { if envs == nil {
return nil return
} }
defer win32.FreeEnvironmentStringsW(envs) defer win32.FreeEnvironmentStringsW(envs)
@@ -82,7 +82,13 @@ _environ :: proc(allocator: runtime.Allocator) -> []string {
} }
} }
r := make([dynamic]string, 0, n, allocator) r := make([dynamic]string, 0, n, allocator) or_return
defer if err != nil {
for e in r {
delete(e, allocator)
}
delete(r)
}
for from, i, p := 0, 0, envs; true; i += 1 { for from, i, p := 0, 0, envs; true; i += 1 {
c := ([^]u16)(p)[i] c := ([^]u16)(p)[i]
if c == 0 { if c == 0 {
@@ -90,12 +96,14 @@ _environ :: proc(allocator: runtime.Allocator) -> []string {
break break
} }
w := ([^]u16)(p)[from:i] w := ([^]u16)(p)[from:i]
append(&r, win32_utf16_to_utf8(w, allocator) or_else "") s := win32_utf16_to_utf8(w, allocator) or_return
append(&r, s)
from = i + 1 from = i + 1
} }
} }
return r[:] environ = r[:]
return
} }
+1 -1
View File
@@ -427,7 +427,7 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
command_line_w := win32_utf8_to_wstring(command_line, temp_allocator()) or_return command_line_w := win32_utf8_to_wstring(command_line, temp_allocator()) or_return
environment := desc.env environment := desc.env
if desc.env == nil { if desc.env == nil {
environment = environ(temp_allocator()) environment = environ(temp_allocator()) or_return
} }
environment_block := _build_environment_block(environment, temp_allocator()) environment_block := _build_environment_block(environment, temp_allocator())
environment_block_w := win32_utf8_to_utf16(environment_block, temp_allocator()) or_return environment_block_w := win32_utf8_to_utf16(environment_block, temp_allocator()) or_return