github.com/dara-project/godist@v0.0.0-20200823115410-e0c80c8f0c78/src/syscall/env_unix.go (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris 6 7 // Unix environment variables. 8 9 package syscall 10 11 import "dara" 12 import "runtime" 13 import "sync" 14 15 var ( 16 // envOnce guards initialization by copyenv, which populates env. 17 envOnce sync.Once 18 19 // envLock guards env and envs. 20 envLock sync.RWMutex 21 22 // env maps from an environment variable to its first occurrence in envs. 23 env map[string]int 24 25 // envs is provided by the runtime. elements are expected to 26 // be of the form "key=value". An empty string means deleted 27 // (or a duplicate to be ignored). 28 envs []string = runtime_envs() 29 ) 30 31 func runtime_envs() []string // in package runtime 32 33 // setenv_c and unsetenv_c are provided by the runtime but are no-ops 34 // if cgo isn't loaded. 35 func setenv_c(k, v string) 36 func unsetenv_c(k string) 37 38 func copyenv() { 39 env = make(map[string]int) 40 for i, s := range envs { 41 for j := 0; j < len(s); j++ { 42 if s[j] == '=' { 43 key := s[:j] 44 if _, ok := env[key]; !ok { 45 env[key] = i // first mention of key 46 } else { 47 // Clear duplicate keys. This permits Unsetenv to 48 // safely delete only the first item without 49 // worrying about unshadowing a later one, 50 // which might be a security problem. 51 envs[i] = "" 52 } 53 break 54 } 55 } 56 } 57 } 58 59 func Unsetenv(key string) error { 60 envOnce.Do(copyenv) 61 62 envLock.Lock() 63 defer envLock.Unlock() 64 65 if i, ok := env[key]; ok { 66 envs[i] = "" 67 delete(env, key) 68 } 69 unsetenv_c(key) 70 // DARA Instrumentation 71 if (runtime.Is_dara_profiling_on()) { 72 runtime.Dara_Debug_Print(func() { println("[UNSETENV] : " + key) }) 73 argInfo := dara.GeneralType{Type: dara.STRING} 74 copy(argInfo.String[:], key) 75 retInfo := dara.GeneralType{Type: dara.ERROR, Unsupported : dara.UNSUPPORTEDVAL} 76 syscallInfo := dara.GeneralSyscall{dara.DSYS_UNSETENV, 1, 1, [10]dara.GeneralType{argInfo}, [10]dara.GeneralType{retInfo}} 77 runtime.Report_Syscall_To_Scheduler(dara.DSYS_UNSETENV, syscallInfo) 78 } 79 return nil 80 } 81 82 func Getenv(key string) (value string, found bool) { 83 argInfo := dara.GeneralType{Type: dara.STRING} 84 copy(argInfo.String[:], key) 85 envOnce.Do(copyenv) 86 if len(key) == 0 { 87 return "", false 88 } 89 90 envLock.RLock() 91 defer envLock.RUnlock() 92 93 i, ok := env[key] 94 if !ok { 95 // DARA Instrumentation 96 if (runtime.Is_dara_profiling_on()) { 97 runtime.Dara_Debug_Print(func() { println("[GETENV] : " + key) }) 98 retInfo1 := dara.GeneralType{Type: dara.STRING} 99 retInfo2 := dara.GeneralType{Type: dara.BOOL, Bool:false} 100 syscallInfo := dara.GeneralSyscall{dara.DSYS_GETENV, 1, 2, [10]dara.GeneralType{argInfo}, [10]dara.GeneralType{retInfo1, retInfo2}} 101 runtime.Report_Syscall_To_Scheduler(dara.DSYS_GETENV, syscallInfo) 102 } 103 return "", false 104 } 105 s := envs[i] 106 for i := 0; i < len(s); i++ { 107 if s[i] == '=' { 108 // DARA Instrumentation 109 if (runtime.Is_dara_profiling_on()) { 110 runtime.Dara_Debug_Print(func() {println("[GETENV] : " + key)}) 111 retInfo1 := dara.GeneralType{Type: dara.STRING} 112 copy(retInfo1.String[:], s[i+1:]) 113 retInfo2 := dara.GeneralType{Type: dara.BOOL, Bool:false} 114 syscallInfo := dara.GeneralSyscall{dara.DSYS_GETENV, 1, 2, [10]dara.GeneralType{argInfo}, [10]dara.GeneralType{retInfo1, retInfo2}} 115 runtime.Report_Syscall_To_Scheduler(dara.DSYS_GETENV, syscallInfo) 116 } 117 return s[i+1:], true 118 } 119 } 120 // DARA Instrumentation 121 if (runtime.Is_dara_profiling_on()) { 122 runtime.Dara_Debug_Print(func() { println("[GETENV] : " + key) }) 123 retInfo1 := dara.GeneralType{Type: dara.STRING} 124 retInfo2 := dara.GeneralType{Type: dara.BOOL, Bool:false} 125 syscallInfo := dara.GeneralSyscall{dara.DSYS_GETENV, 1, 2, [10]dara.GeneralType{argInfo}, [10]dara.GeneralType{retInfo1, retInfo2}} 126 runtime.Report_Syscall_To_Scheduler(dara.DSYS_GETENV, syscallInfo) 127 } 128 return "", false 129 } 130 131 func Setenv(key, value string) error { 132 // DARA Instrumentation 133 if (runtime.Is_dara_profiling_on()) { 134 runtime.Dara_Debug_Print(func() { println("[SETENV] : " + key + " " + value) }) 135 argInfo1 := dara.GeneralType{Type: dara.STRING} 136 copy(argInfo1.String[:], key) 137 argInfo2 := dara.GeneralType{Type: dara.STRING} 138 copy(argInfo2.String[:], value) 139 retInfo := dara.GeneralType{Type: dara.ERROR, Unsupported : dara.UNSUPPORTEDVAL} 140 syscallInfo := dara.GeneralSyscall{dara.DSYS_GETENV, 2, 1, [10]dara.GeneralType{argInfo1, argInfo2}, [10]dara.GeneralType{retInfo}} 141 runtime.Report_Syscall_To_Scheduler(dara.DSYS_SETENV, syscallInfo) 142 } 143 envOnce.Do(copyenv) 144 if len(key) == 0 { 145 return EINVAL 146 } 147 for i := 0; i < len(key); i++ { 148 if key[i] == '=' || key[i] == 0 { 149 return EINVAL 150 } 151 } 152 for i := 0; i < len(value); i++ { 153 if value[i] == 0 { 154 return EINVAL 155 } 156 } 157 158 envLock.Lock() 159 defer envLock.Unlock() 160 161 i, ok := env[key] 162 kv := key + "=" + value 163 if ok { 164 envs[i] = kv 165 } else { 166 i = len(envs) 167 envs = append(envs, kv) 168 } 169 env[key] = i 170 setenv_c(key, value) 171 return nil 172 } 173 174 func Clearenv() { 175 envOnce.Do(copyenv) // prevent copyenv in Getenv/Setenv 176 177 envLock.Lock() 178 defer envLock.Unlock() 179 180 for k := range env { 181 unsetenv_c(k) 182 } 183 env = make(map[string]int) 184 envs = []string{} 185 // DARA Instrumentation 186 if (runtime.Is_dara_profiling_on()) { 187 runtime.Dara_Debug_Print(func() { println("[CLEARENV]") }) 188 syscallInfo := dara.GeneralSyscall{dara.DSYS_CLEARENV, 0, 0, [10]dara.GeneralType{}, [10]dara.GeneralType{}} 189 runtime.Report_Syscall_To_Scheduler(dara.DSYS_CLEARENV, syscallInfo) 190 } 191 } 192 193 func Environ() []string { 194 envOnce.Do(copyenv) 195 envLock.RLock() 196 defer envLock.RUnlock() 197 a := make([]string, 0, len(envs)) 198 for _, env := range envs { 199 if env != "" { 200 a = append(a, env) 201 } 202 } 203 // DARA Instrumentation 204 if (runtime.Is_dara_profiling_on()) { 205 runtime.Dara_Debug_Print(func() { println("[ENVIRON]") }) 206 retInfo := dara.GeneralType{Type: dara.ARRAY, Integer: len(a)} 207 syscallInfo := dara.GeneralSyscall{dara.DSYS_ENVIRON, 0, 1, [10]dara.GeneralType{}, [10]dara.GeneralType{retInfo}} 208 runtime.Report_Syscall_To_Scheduler(dara.DSYS_ENVIRON, syscallInfo) 209 } 210 return a 211 }