mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-15 15:44:04 +00:00
111 lines
2.3 KiB
Odin
111 lines
2.3 KiB
Odin
#+private
|
|
#+build darwin, netbsd, freebsd, openbsd
|
|
package os
|
|
|
|
import "base:runtime"
|
|
|
|
import "core:strings"
|
|
import "core:sys/posix"
|
|
|
|
_lookup_env_alloc :: proc(key: string, allocator: runtime.Allocator) -> (value: string, found: bool) {
|
|
if key == "" {
|
|
return
|
|
}
|
|
|
|
temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
|
|
|
|
ckey := strings.clone_to_cstring(key, temp_allocator)
|
|
cval := posix.getenv(ckey)
|
|
if cval == nil {
|
|
return
|
|
}
|
|
|
|
found = true
|
|
value = strings.clone(string(cval), allocator) // NOTE(laytan): what if allocation fails?
|
|
|
|
return
|
|
}
|
|
|
|
_lookup_env_buf :: proc(buf: []u8, key: string) -> (value: string, error: Error) {
|
|
if key == "" {
|
|
return
|
|
}
|
|
|
|
if len(key) + 1 > len(buf) {
|
|
return "", .Buffer_Full
|
|
} else {
|
|
copy(buf, key)
|
|
buf[len(key)] = 0
|
|
}
|
|
|
|
cval := posix.getenv(cstring(raw_data(buf)))
|
|
if cval == nil {
|
|
return
|
|
}
|
|
|
|
if value = string(cval); value == "" {
|
|
return "", .Env_Var_Not_Found
|
|
} else {
|
|
if len(value) > len(buf) {
|
|
return "", .Buffer_Full
|
|
} else {
|
|
copy(buf, value)
|
|
return string(buf[:len(value)]), nil
|
|
}
|
|
}
|
|
}
|
|
|
|
_lookup_env :: proc{_lookup_env_alloc, _lookup_env_buf}
|
|
|
|
_set_env :: proc(key, value: string) -> (err: Error) {
|
|
temp_allocator := TEMP_ALLOCATOR_GUARD({})
|
|
|
|
ckey := strings.clone_to_cstring(key, temp_allocator) or_return
|
|
cval := strings.clone_to_cstring(value, temp_allocator) or_return
|
|
|
|
if posix.setenv(ckey, cval, true) != nil {
|
|
err = _get_platform_error_from_errno()
|
|
}
|
|
return
|
|
}
|
|
|
|
_unset_env :: proc(key: string) -> (ok: bool) {
|
|
temp_allocator := TEMP_ALLOCATOR_GUARD({})
|
|
|
|
ckey := strings.clone_to_cstring(key, temp_allocator)
|
|
|
|
ok = posix.unsetenv(ckey) == .OK
|
|
return
|
|
}
|
|
|
|
// NOTE(laytan): clearing the env is weird, why would you ever do that?
|
|
|
|
_clear_env :: proc() {
|
|
for entry := posix.environ[0]; entry != nil; entry = posix.environ[0] {
|
|
key := strings.truncate_to_byte(string(entry), '=')
|
|
_unset_env(key)
|
|
}
|
|
}
|
|
|
|
_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] {}
|
|
|
|
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] {
|
|
append(&r, strings.clone(string(entry), allocator) or_return)
|
|
}
|
|
|
|
environ = r[:]
|
|
return
|
|
}
|
|
|
|
|