Răsfoiți Sursa

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

gingerBill 6 luni în urmă
părinte
comite
b3bbb00f1a

+ 1 - 1
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)
 }
 

+ 13 - 5
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,

+ 9 - 9
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
 }
 

+ 8 - 19
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
 }

+ 14 - 6
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..<len(env) {
 			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()
 	if envs == nil {
-		return nil
+		return
 	}
 	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 {
 		c := ([^]u16)(p)[i]
 		if c == 0 {
@@ -90,12 +96,14 @@ _environ :: proc(allocator: runtime.Allocator) -> []string {
 				break
 			}
 			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
 		}
 	}
 
-	return r[:]
+	environ = r[:]
+	return
 }
 
 

+ 1 - 1
core/os/os2/process_windows.odin

@@ -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
 	environment := desc.env
 	if desc.env == nil {
-		environment = environ(temp_allocator())
+		environment = environ(temp_allocator()) or_return
 	}
 	environment_block   := _build_environment_block(environment, temp_allocator())
 	environment_block_w := win32_utf8_to_utf16(environment_block, temp_allocator()) or_return