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