mirror of https://github.com/golang/go.git
syscall: don't cache environment variables on Plan 9
Fixes #8849. LGTM=bradfitz, aram R=bradfitz, rsc, aram CC=golang-codereviews https://golang.org/cl/158970045
This commit is contained in:
parent
25f79b9dbe
commit
70896a78fa
|
|
@ -8,28 +8,9 @@ package syscall
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// envOnce guards copyenv, which populates env, envi and envs.
|
||||
envOnce sync.Once
|
||||
|
||||
// envLock guards env, envi and envs.
|
||||
envLock sync.RWMutex
|
||||
|
||||
// env maps from an environment variable to its value.
|
||||
// TODO: remove this? golang.org/issue/8849
|
||||
env = make(map[string]string)
|
||||
|
||||
// envi maps from an environment variable to its index in envs.
|
||||
// TODO: remove this? golang.org/issue/8849
|
||||
envi = make(map[string]int)
|
||||
|
||||
// envs contains elements of env in the form "key=value".
|
||||
// empty strings mean deleted.
|
||||
envs []string
|
||||
|
||||
errZeroLengthKey = errors.New("zero length key")
|
||||
errShortWrite = errors.New("i/o count too small")
|
||||
)
|
||||
|
|
@ -70,47 +51,14 @@ func writeenv(key, value string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func copyenv() {
|
||||
fd, err := Open("/env", O_RDONLY)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer Close(fd)
|
||||
files, err := readdirnames(fd)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
envs = make([]string, len(files))
|
||||
i := 0
|
||||
for _, key := range files {
|
||||
v, err := readenv(key)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
env[key] = v
|
||||
envs[i] = key + "=" + v
|
||||
envi[key] = i
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
func Getenv(key string) (value string, found bool) {
|
||||
if len(key) == 0 {
|
||||
return "", false
|
||||
}
|
||||
|
||||
envLock.RLock()
|
||||
defer envLock.RUnlock()
|
||||
|
||||
if v, ok := env[key]; ok {
|
||||
return v, true
|
||||
}
|
||||
v, err := readenv(key)
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
env[key] = v
|
||||
envs = append(envs, key+"="+v)
|
||||
return v, true
|
||||
}
|
||||
|
||||
|
|
@ -118,27 +66,14 @@ func Setenv(key, value string) error {
|
|||
if len(key) == 0 {
|
||||
return errZeroLengthKey
|
||||
}
|
||||
|
||||
envLock.Lock()
|
||||
defer envLock.Unlock()
|
||||
|
||||
err := writeenv(key, value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
env[key] = value
|
||||
envs = append(envs, key+"="+value)
|
||||
envi[key] = len(envs) - 1
|
||||
return nil
|
||||
}
|
||||
|
||||
func Clearenv() {
|
||||
envLock.Lock()
|
||||
defer envLock.Unlock()
|
||||
|
||||
env = make(map[string]string)
|
||||
envi = make(map[string]int)
|
||||
envs = []string{}
|
||||
RawSyscall(SYS_RFORK, RFCENVG, 0, 0)
|
||||
}
|
||||
|
||||
|
|
@ -146,30 +81,28 @@ func Unsetenv(key string) error {
|
|||
if len(key) == 0 {
|
||||
return errZeroLengthKey
|
||||
}
|
||||
|
||||
envLock.Lock()
|
||||
defer envLock.Unlock()
|
||||
|
||||
Remove("/env/" + key)
|
||||
|
||||
if i, ok := envi[key]; ok {
|
||||
delete(env, key)
|
||||
delete(envi, key)
|
||||
envs[i] = ""
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Environ() []string {
|
||||
envLock.RLock()
|
||||
defer envLock.RUnlock()
|
||||
fd, err := Open("/env", O_RDONLY)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer Close(fd)
|
||||
files, err := readdirnames(fd)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
ret := make([]string, 0, len(files))
|
||||
|
||||
envOnce.Do(copyenv)
|
||||
ret := make([]string, 0, len(envs))
|
||||
for _, pair := range envs {
|
||||
if pair != "" {
|
||||
ret = append(ret, pair)
|
||||
for _, key := range files {
|
||||
v, err := readenv(key)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ret = append(ret, key+"="+v)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue