Source file
src/syscall/env_unix.go
1
2
3
4
5
6
7
8
9 package syscall
10
11 import (
12 "runtime"
13 "sync"
14 )
15
16 var (
17
18 envOnce sync.Once
19
20
21 envLock sync.RWMutex
22
23
24 env map[string]int
25
26
27
28
29 envs []string = runtime_envs()
30 )
31
32 func runtime_envs() []string
33
34 func copyenv() {
35 env = make(map[string]int)
36 for i, s := range envs {
37 for j := 0; j < len(s); j++ {
38 if s[j] == '=' {
39 key := s[:j]
40 if _, ok := env[key]; !ok {
41 env[key] = i
42 } else {
43
44
45
46
47 envs[i] = ""
48 }
49 break
50 }
51 }
52 }
53 }
54
55 func Unsetenv(key string) error {
56 envOnce.Do(copyenv)
57
58 envLock.Lock()
59 defer envLock.Unlock()
60
61 if i, ok := env[key]; ok {
62 envs[i] = ""
63 delete(env, key)
64 }
65 runtimeUnsetenv(key)
66 return nil
67 }
68
69 func Getenv(key string) (value string, found bool) {
70 envOnce.Do(copyenv)
71 if len(key) == 0 {
72 return "", false
73 }
74
75 envLock.RLock()
76 defer envLock.RUnlock()
77
78 i, ok := env[key]
79 if !ok {
80 return "", false
81 }
82 s := envs[i]
83 for i := 0; i < len(s); i++ {
84 if s[i] == '=' {
85 return s[i+1:], true
86 }
87 }
88 return "", false
89 }
90
91 func Setenv(key, value string) error {
92 envOnce.Do(copyenv)
93 if len(key) == 0 {
94 return EINVAL
95 }
96 for i := 0; i < len(key); i++ {
97 if key[i] == '=' || key[i] == 0 {
98 return EINVAL
99 }
100 }
101
102 if runtime.GOOS != "plan9" {
103 for i := 0; i < len(value); i++ {
104 if value[i] == 0 {
105 return EINVAL
106 }
107 }
108 }
109
110 envLock.Lock()
111 defer envLock.Unlock()
112
113 i, ok := env[key]
114 kv := key + "=" + value
115 if ok {
116 envs[i] = kv
117 } else {
118 i = len(envs)
119 envs = append(envs, kv)
120 }
121 env[key] = i
122 runtimeSetenv(key, value)
123 return nil
124 }
125
126 func Clearenv() {
127 envOnce.Do(copyenv)
128
129 envLock.Lock()
130 defer envLock.Unlock()
131
132 for k := range env {
133 runtimeUnsetenv(k)
134 }
135 env = make(map[string]int)
136 envs = []string{}
137 }
138
139 func Environ() []string {
140 envOnce.Do(copyenv)
141 envLock.RLock()
142 defer envLock.RUnlock()
143 a := make([]string, 0, len(envs))
144 for _, env := range envs {
145 if env != "" {
146 a = append(a, env)
147 }
148 }
149 return a
150 }
151
View as plain text