ref: 7c4d2abbe14d3d0e9d2f5872e0964677c5dc783d
dir: /lib/std/env+posixy.myr/
use sys
use "alloc"
use "cstrconv"
use "die"
use "extremum"
use "fmt"
use "sleq"
use "memops"
use "option"
use "slcp"
use "sldup"
use "slpush"
use "threadhooks"
use "traits"
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
if envp != Zenvp
env = cstrconvp(envp)
n = min(name.len, env.len)
if eq(name, env[:n]) && eq(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, found
envinit()
idx = 0
found = false
e = fmt("{}={}\0", name, val)
lock(envlck)
for envp : environ
if envp != Zenvp
env = cstrconvp(envp)
n = min(name.len, env.len - 1)
if eq(name, env[:n]) && env[n] == ('=' : byte)
found = true
break
;;
idx++
;;
;;
if !found
idx = env.len - 1
std.slpush(&environ, Zenvp)
;;
e = cstrconvp(environ[idx])
sys.__cenvp = (environ : byte##)
unlock(envlck)
}
const envinit = {
var len, e, p
lock(envlck)
if environ.len != 0
unlock(envlck)
-> void
;;
/*
Here, we duplicate the environment so we can
modify it. We take progressively bigger slices
as we go, until we find the terminating null.
It's a bit ugly, but what do?
*/
len = 0
environ = [][:]
while true
p = sys.__cenvp[:len+1][len]
if p != Zenvp
e = sldup(cstrconvp(p))
slpush(&e, 0)
p = (e : byte#)
;;
std.slpush(&environ, p)
if environ[len] == Zenvp
break
;;
len++
;;
sys.__cenvp = (environ : byte##)
unlock(envlck)
}