github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/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 netbsd openbsd 6 7 // Unix environment variables. 8 9 package syscall 10 11 import "sync" 12 13 var ( 14 // envOnce guards initialization by copyenv, which populates env. 15 envOnce sync.Once 16 17 // envLock guards env and envs. 18 envLock sync.RWMutex 19 20 // env maps from an environment variable to its first occurrence in envs. 21 env map[string]int 22 23 // envs is provided by the runtime. elements are expected to be 24 // of the form "key=value". 25 envs []string 26 ) 27 28 // setenv_c is provided by the runtime, but is a no-op if cgo isn't 29 // loaded. 30 func setenv_c(k, v string) 31 32 func copyenv() { 33 env = make(map[string]int) 34 for i, s := range envs { 35 for j := 0; j < len(s); j++ { 36 if s[j] == '=' { 37 key := s[:j] 38 if _, ok := env[key]; !ok { 39 env[key] = i 40 } 41 break 42 } 43 } 44 } 45 } 46 47 func Getenv(key string) (value string, found bool) { 48 envOnce.Do(copyenv) 49 if len(key) == 0 { 50 return "", false 51 } 52 53 envLock.RLock() 54 defer envLock.RUnlock() 55 56 i, ok := env[key] 57 if !ok { 58 return "", false 59 } 60 s := envs[i] 61 for i := 0; i < len(s); i++ { 62 if s[i] == '=' { 63 return s[i+1:], true 64 } 65 } 66 return "", false 67 } 68 69 func Setenv(key, value string) error { 70 envOnce.Do(copyenv) 71 if len(key) == 0 { 72 return EINVAL 73 } 74 for i := 0; i < len(key); i++ { 75 if key[i] == '=' || key[i] == 0 { 76 return EINVAL 77 } 78 } 79 for i := 0; i < len(value); i++ { 80 if value[i] == 0 { 81 return EINVAL 82 } 83 } 84 85 envLock.Lock() 86 defer envLock.Unlock() 87 88 i, ok := env[key] 89 kv := key + "=" + value 90 if ok { 91 envs[i] = kv 92 } else { 93 i = len(envs) 94 envs = append(envs, kv) 95 } 96 env[key] = i 97 setenv_c(key, value) 98 return nil 99 } 100 101 func Clearenv() { 102 envOnce.Do(copyenv) // prevent copyenv in Getenv/Setenv 103 104 envLock.Lock() 105 defer envLock.Unlock() 106 107 env = make(map[string]int) 108 envs = []string{} 109 // TODO(bradfitz): pass through to C 110 } 111 112 func Environ() []string { 113 envOnce.Do(copyenv) 114 envLock.RLock() 115 defer envLock.RUnlock() 116 a := make([]string, len(envs)) 117 copy(a, envs) 118 return a 119 }