| |
| |
| |
|
|
| |
|
|
| |
|
|
| package syscall |
|
|
| import ( |
| "runtime" |
| "sync" |
| ) |
|
|
| var ( |
| |
| envLock sync.RWMutex |
|
|
| |
| env map[string]int |
|
|
| |
| |
| |
| envs []string = runtime_envs() |
| ) |
|
|
| func runtime_envs() []string |
|
|
| var copyenv = sync.OnceFunc(func() { |
| 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 |
| } else { |
| |
| |
| |
| |
| envs[i] = "" |
| } |
| break |
| } |
| } |
| } |
| }) |
|
|
| func Unsetenv(key string) error { |
| copyenv() |
|
|
| envLock.Lock() |
| defer envLock.Unlock() |
|
|
| if i, ok := env[key]; ok { |
| envs[i] = "" |
| delete(env, key) |
| } |
| runtimeUnsetenv(key) |
| return nil |
| } |
|
|
| func Getenv(key string) (value string, found bool) { |
| 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 { |
| copyenv() |
| if len(key) == 0 { |
| return EINVAL |
| } |
| for i := 0; i < len(key); i++ { |
| if key[i] == '=' || key[i] == 0 { |
| return EINVAL |
| } |
| } |
| |
| if runtime.GOOS != "plan9" { |
| 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 |
| runtimeSetenv(key, value) |
| return nil |
| } |
|
|
| func Clearenv() { |
| copyenv() |
|
|
| envLock.Lock() |
| defer envLock.Unlock() |
|
|
| runtimeClearenv(env) |
|
|
| env = make(map[string]int) |
| envs = []string{} |
| } |
|
|
| func Environ() []string { |
| copyenv() |
| envLock.RLock() |
| defer envLock.RUnlock() |
| a := make([]string, 0, len(envs)) |
| for _, env := range envs { |
| if env != "" { |
| a = append(a, env) |
| } |
| } |
| return a |
| } |
|
|