Files
llgo/runtime/internal/clite/syscall/env_unix.go
2025-04-11 16:28:44 +08:00

70 lines
1.2 KiB
Go

package syscall
import (
"sync"
_ "unsafe"
c "github.com/goplus/llgo/runtime/internal/clite"
)
var (
envOnce sync.Once
envLock sync.RWMutex
env map[string]int
envs []string
)
//go:linkname c_environ environ
var c_environ **c.Char
//go:linkname c_getenv C.getenv
func c_getenv(name *c.Char) *c.Char
func copyenv() {
env = make(map[string]int)
p := c_environ
i := 0
for p != nil {
s := c.GoString(*p)
for j := 0; j < len(s); j++ {
if s[j] == '=' {
key := s[:j]
if _, ok := env[key]; !ok {
env[key] = i // first mention of key
} else {
// Clear duplicate keys. This permits Unsetenv to
// safely delete only the first item without
// worrying about unshadowing a later one,
// which might be a security problem.
envs[i] = ""
}
break
}
}
p = c.Advance(p, 1)
i++
}
}
func Getenv(key string) (value string, found bool) {
envOnce.Do(copyenv)
if len(key) == 0 {
return "", false
}
envLock.RLock()
defer envLock.RUnlock()
i, ok := env[key]
if !ok {
return "", false
}
s := envs[i]
for i := 0; i < len(s); i++ {
if s[i] == '=' {
return s[i+1:], true
}
}
return "", false
}