mirror of
https://github.com/autc04/Retro68.git
synced 2024-12-03 10:49:58 +00:00
110 lines
1.9 KiB
Go
110 lines
1.9 KiB
Go
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
// +build darwin freebsd linux netbsd openbsd
|
||
|
|
||
|
// Unix environment variables.
|
||
|
|
||
|
package syscall
|
||
|
|
||
|
import "sync"
|
||
|
|
||
|
var (
|
||
|
// envOnce guards initialization by copyenv, which populates env.
|
||
|
envOnce sync.Once
|
||
|
|
||
|
// envLock guards env and envs.
|
||
|
envLock sync.RWMutex
|
||
|
|
||
|
// env maps from an environment variable to its first occurrence in envs.
|
||
|
env map[string]int
|
||
|
|
||
|
// envs is provided by the runtime. elements are expected to be
|
||
|
// of the form "key=value".
|
||
|
Envs []string
|
||
|
)
|
||
|
|
||
|
// setenv_c is provided by the runtime, but is a no-op if cgo isn't
|
||
|
// loaded.
|
||
|
func setenv_c(k, v string)
|
||
|
|
||
|
func copyenv() {
|
||
|
env = make(map[string]int)
|
||
|
for i, s := range Envs {
|
||
|
for j := 0; j < len(s); j++ {
|
||
|
if s[j] == '=' {
|
||
|
key := s[:j]
|
||
|
if _, ok := env[key]; !ok {
|
||
|
env[key] = i
|
||
|
}
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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
|
||
|
}
|
||
|
|
||
|
func Setenv(key, value string) error {
|
||
|
envOnce.Do(copyenv)
|
||
|
if len(key) == 0 {
|
||
|
return EINVAL
|
||
|
}
|
||
|
|
||
|
envLock.Lock()
|
||
|
defer envLock.Unlock()
|
||
|
|
||
|
i, ok := env[key]
|
||
|
kv := key + "=" + value
|
||
|
if ok {
|
||
|
Envs[i] = kv
|
||
|
} else {
|
||
|
i = len(Envs)
|
||
|
Envs = append(Envs, kv)
|
||
|
}
|
||
|
env[key] = i
|
||
|
setenv_c(key, value)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func Clearenv() {
|
||
|
envOnce.Do(copyenv) // prevent copyenv in Getenv/Setenv
|
||
|
|
||
|
envLock.Lock()
|
||
|
defer envLock.Unlock()
|
||
|
|
||
|
env = make(map[string]int)
|
||
|
Envs = []string{}
|
||
|
// TODO(bradfitz): pass through to C
|
||
|
}
|
||
|
|
||
|
func Environ() []string {
|
||
|
envOnce.Do(copyenv)
|
||
|
envLock.RLock()
|
||
|
defer envLock.RUnlock()
|
||
|
a := make([]string, len(Envs))
|
||
|
copy(a, Envs)
|
||
|
return a
|
||
|
}
|