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
111
112
113
|
use sys
use "alloc"
use "cstrconv"
use "die"
use "extremum"
use "fmt"
use "memops"
use "option"
use "sldup"
use "slcp"
use "sleq"
use "slpush"
pkg std =
const getenv : (name : byte[:] -> option(byte[:]))
const getenvv : (name : byte[:], default : byte[:] -> byte[:])
const setenv : (name : byte[:], val : byte[:] -> void)
;;
const Zenvp = (0 : byte#)
var envduped : bool = false
var environ : byte#[:]
const getenv = {name
var n, env
envinit()
for envp : environ
env = cstrconvp(envp)
n = min(name.len, env.len)
if sleq(name, env[:n]) && sleq(env[n:n+1], "=")
-> `Some env[n+1:]
;;
;;
-> `None
}
const getenvv = {name, default
match getenv(name)
| `Some v: -> v
| `None: -> default
;;
}
const setenv = {name, val
var n, e, env, idx
envdup()
idx = 0
for envp : environ
if envp == Zenvp
break
;;
env = cstrconvp(envp)
n = min(name.len, env.len)
if sleq(name, env[:n]) && sleq(env[n:n+1], "=")
break
;;
idx++
;;
if idx == environ.len - 1
slpush(&environ, (0 : byte#))
else
e = cstrconvp(environ[idx])
std.slfree(e)
;;
e = fmt("{}={}\0", name, val)
environ[idx] = (e : byte#)
sys.__cenvp = (environ : byte##)
}
const envinit = {
var len
if environ.len != 0
-> void
;;
environ = sys.__cenvp[:1]
len = 0
while true
len++
environ = sys.__cenvp[:len + 1]
if environ[len] == Zenvp
environ = sys.__cenvp[:len]
break
;;
;;
}
const envdup = {
var e, s, dup
if envduped
-> void
;;
envduped = true
envinit()
dup = std.slalloc(environ.len + 1)
for var i = 0; i < environ.len; i++
s = cstrconvp(environ[i])
e = std.slalloc(s.len + 1)
slcp(e[:e.len - 1], s)
e[e.len - 1] = 0
dup[i] = (e : byte#)
;;
dup[dup.len - 1] = Zenvp
environ = dup[:dup.len - 1]
sys.__cenvp = (environ : byte##)
}
|