diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-26 14:53:25 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-26 14:53:25 +0000 |
commit | 9e1b949cce0f9ef70dcd4afbe5868e0d95df1281 (patch) | |
tree | 137b86fc61b9e2f6e640c75c064cffb9b909e79a /libgo/go/syscall/env_unix.go | |
parent | 9b040c42465165aa265b581d597878f799c29ad0 (diff) | |
download | gcc-9e1b949cce0f9ef70dcd4afbe5868e0d95df1281.tar.gz |
2012-01-26 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 183561 using svnmerge
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@183563 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/syscall/env_unix.go')
-rw-r--r-- | libgo/go/syscall/env_unix.go | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/libgo/go/syscall/env_unix.go b/libgo/go/syscall/env_unix.go index 3ba0fb1b098..c1a02135f4f 100644 --- a/libgo/go/syscall/env_unix.go +++ b/libgo/go/syscall/env_unix.go @@ -10,26 +10,40 @@ package syscall import "sync" -var env map[string]string -var envOnce sync.Once -var Envs []string // provided by runtime +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]string) - for _, s := range Envs { + env = make(map[string]int) + for i, s := range Envs { for j := 0; j < len(s); j++ { if s[j] == '=' { - env[s[0:j]] = s[j+1:] + key := s[:j] + if _, ok := env[key]; !ok { + env[key] = i + } break } } } } -var envLock sync.RWMutex - func Getenv(key string) (value string, found bool) { envOnce.Do(copyenv) if len(key) == 0 { @@ -39,11 +53,17 @@ func Getenv(key string) (value string, found bool) { envLock.RLock() defer envLock.RUnlock() - v, ok := env[key] + i, ok := env[key] if !ok { return "", false } - return v, true + 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 { @@ -55,8 +75,16 @@ func Setenv(key, value string) error { envLock.Lock() defer envLock.Unlock() - env[key] = value - setenv_c(key, value) // is a no-op if cgo isn't loaded + 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 } @@ -66,8 +94,8 @@ func Clearenv() { envLock.Lock() defer envLock.Unlock() - env = make(map[string]string) - + env = make(map[string]int) + Envs = []string{} // TODO(bradfitz): pass through to C } @@ -75,11 +103,7 @@ func Environ() []string { envOnce.Do(copyenv) envLock.RLock() defer envLock.RUnlock() - a := make([]string, len(env)) - i := 0 - for k, v := range env { - a[i] = k + "=" + v - i++ - } + a := make([]string, len(Envs)) + copy(a, Envs) return a } |