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