LEFT | RIGHT |
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris | 5 // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris |
6 | 6 |
7 // Unix environment variables. | 7 // Unix environment variables. |
8 | 8 |
9 package syscall | 9 package syscall |
10 | 10 |
11 import "sync" | 11 import "sync" |
12 | 12 |
13 var ( | 13 var ( |
14 // envOnce guards initialization by copyenv, which populates env. | 14 // envOnce guards initialization by copyenv, which populates env. |
15 envOnce sync.Once | 15 envOnce sync.Once |
16 | 16 |
17 // envLock guards env and envs. | 17 // envLock guards env and envs. |
18 envLock sync.RWMutex | 18 envLock sync.RWMutex |
19 | 19 |
20 // env maps from an environment variable to its first occurrence in envs
. | 20 // env maps from an environment variable to its first occurrence in envs
. |
21 env map[string]int | 21 env map[string]int |
22 | 22 |
23 » // envs is provided by the runtime. elements are expected to be | 23 » // envs is provided by the runtime. elements are expected to |
24 » // of the form "key=value". | 24 » // be of the form "key=value". An empty string means deleted |
| 25 » // (or a duplicate to be ignored). |
25 envs []string = runtime_envs() | 26 envs []string = runtime_envs() |
26 ) | 27 ) |
27 | 28 |
28 func runtime_envs() []string // in package runtime | 29 func runtime_envs() []string // in package runtime |
29 | 30 |
30 // setenv_c and unsetenv_c are provided by the runtime but are no-ops | 31 // setenv_c and unsetenv_c are provided by the runtime but are no-ops |
31 // if cgo isn't loaded. | 32 // if cgo isn't loaded. |
32 func setenv_c(k, v string) | 33 func setenv_c(k, v string) |
33 func unsetenv_c(k string) | 34 func unsetenv_c(k string) |
34 | 35 |
35 func copyenv() { | 36 func copyenv() { |
36 env = make(map[string]int) | 37 env = make(map[string]int) |
37 for i, s := range envs { | 38 for i, s := range envs { |
38 for j := 0; j < len(s); j++ { | 39 for j := 0; j < len(s); j++ { |
39 if s[j] == '=' { | 40 if s[j] == '=' { |
40 key := s[:j] | 41 key := s[:j] |
41 if _, ok := env[key]; !ok { | 42 if _, ok := env[key]; !ok { |
42 » » » » » env[key] = i | 43 » » » » » env[key] = i // first mention of key |
| 44 » » » » } else { |
| 45 » » » » » // Clear duplicate keys. This permits Un
setenv to |
| 46 » » » » » // safely delete only the first item wit
hout |
| 47 » » » » » // worrying about unshadowing a later on
e, |
| 48 » » » » » // which might be a security problem. |
| 49 » » » » » envs[i] = "" |
43 } | 50 } |
44 break | 51 break |
45 } | 52 } |
46 } | 53 } |
47 } | 54 } |
48 } | 55 } |
49 | 56 |
50 func Unsetenv(key string) error { | 57 func Unsetenv(key string) error { |
51 envOnce.Do(copyenv) | 58 envOnce.Do(copyenv) |
52 | 59 |
53 envLock.Lock() | 60 envLock.Lock() |
54 defer envLock.Unlock() | 61 defer envLock.Unlock() |
55 | 62 |
56 » // Clear all envs[i] where envs[i] starts with key+"=". | 63 » if i, ok := env[key]; ok { |
57 » // The empty values will be filtered out in Environ. | 64 » » envs[i] = "" |
58 » for i, pair := range envs { | 65 » » delete(env, key) |
59 » » if len(pair) >= len(key)+1 && | |
60 » » » pair[:len(key)] == key && | |
61 » » » pair[len(key)] == '=' { | |
62 » » » envs[i] = "" | |
63 » » } | |
64 } | 66 } |
65 delete(env, key) | |
66 unsetenv_c(key) | 67 unsetenv_c(key) |
67 return nil | 68 return nil |
68 } | 69 } |
69 | 70 |
70 func Getenv(key string) (value string, found bool) { | 71 func Getenv(key string) (value string, found bool) { |
71 envOnce.Do(copyenv) | 72 envOnce.Do(copyenv) |
72 if len(key) == 0 { | 73 if len(key) == 0 { |
73 return "", false | 74 return "", false |
74 } | 75 } |
75 | 76 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 envLock.RLock() | 140 envLock.RLock() |
140 defer envLock.RUnlock() | 141 defer envLock.RUnlock() |
141 a := make([]string, 0, len(envs)) | 142 a := make([]string, 0, len(envs)) |
142 for _, env := range envs { | 143 for _, env := range envs { |
143 if env != "" { | 144 if env != "" { |
144 a = append(a, env) | 145 a = append(a, env) |
145 } | 146 } |
146 } | 147 } |
147 return a | 148 return a |
148 } | 149 } |
LEFT | RIGHT |