1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#+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
}
|