|
|
@@ -8,112 +8,20 @@
|
|
|
|
|
|
package unix
|
|
|
|
|
|
-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
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
+import "syscall"
|
|
|
|
|
|
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
|
|
|
+ return syscall.Getenv(key)
|
|
|
}
|
|
|
|
|
|
func Setenv(key, value string) error {
|
|
|
- envOnce.Do(copyenv)
|
|
|
- if len(key) == 0 {
|
|
|
- return EINVAL
|
|
|
- }
|
|
|
- for i := 0; i < len(key); i++ {
|
|
|
- if key[i] == '=' || key[i] == 0 {
|
|
|
- return EINVAL
|
|
|
- }
|
|
|
- }
|
|
|
- for i := 0; i < len(value); i++ {
|
|
|
- if value[i] == 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
|
|
|
+ return syscall.Setenv(key, value)
|
|
|
}
|
|
|
|
|
|
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
|
|
|
+ syscall.Clearenv()
|
|
|
}
|
|
|
|
|
|
func Environ() []string {
|
|
|
- envOnce.Do(copyenv)
|
|
|
- envLock.RLock()
|
|
|
- defer envLock.RUnlock()
|
|
|
- a := make([]string, len(envs))
|
|
|
- copy(a, envs)
|
|
|
- return a
|
|
|
+ return syscall.Environ()
|
|
|
}
|