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