github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/syscall/env_plan9.go (about) 1 // Copyright 2011 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 // Plan 9 environment variables. 6 7 package syscall 8 9 import ( 10 "errors" 11 "sync" 12 ) 13 14 var ( 15 // envOnce guards copyenv, which populates env. 16 envOnce sync.Once 17 18 // envLock guards env and envs. 19 envLock sync.RWMutex 20 21 // env maps from an environment variable to its value. 22 env = make(map[string]string) 23 24 // envs contains elements of env in the form "key=value". 25 envs []string 26 27 errZeroLengthKey = errors.New("zero length key") 28 errShortWrite = errors.New("i/o count too small") 29 ) 30 31 func readenv(key string) (string, error) { 32 fd, err := Open("/env/"+key, O_RDONLY) 33 if err != nil { 34 return "", err 35 } 36 defer Close(fd) 37 l, _ := Seek(fd, 0, 2) 38 Seek(fd, 0, 0) 39 buf := make([]byte, l) 40 n, err := Read(fd, buf) 41 if err != nil { 42 return "", err 43 } 44 if n > 0 && buf[n-1] == 0 { 45 buf = buf[:n-1] 46 } 47 return string(buf), nil 48 } 49 50 func writeenv(key, value string) error { 51 fd, err := Create("/env/"+key, O_RDWR, 0666) 52 if err != nil { 53 return err 54 } 55 defer Close(fd) 56 b := []byte(value) 57 n, err := Write(fd, b) 58 if err != nil { 59 return err 60 } 61 if n != len(b) { 62 return errShortWrite 63 } 64 return nil 65 } 66 67 func copyenv() { 68 fd, err := Open("/env", O_RDONLY) 69 if err != nil { 70 return 71 } 72 defer Close(fd) 73 files, err := readdirnames(fd) 74 if err != nil { 75 return 76 } 77 envs = make([]string, len(files)) 78 i := 0 79 for _, key := range files { 80 v, err := readenv(key) 81 if err != nil { 82 continue 83 } 84 env[key] = v 85 envs[i] = key + "=" + v 86 i++ 87 } 88 } 89 90 func Getenv(key string) (value string, found bool) { 91 if len(key) == 0 { 92 return "", false 93 } 94 95 envLock.RLock() 96 defer envLock.RUnlock() 97 98 if v, ok := env[key]; ok { 99 return v, true 100 } 101 v, err := readenv(key) 102 if err != nil { 103 return "", false 104 } 105 env[key] = v 106 envs = append(envs, key+"="+v) 107 return v, true 108 } 109 110 func Setenv(key, value string) error { 111 if len(key) == 0 { 112 return errZeroLengthKey 113 } 114 115 envLock.Lock() 116 defer envLock.Unlock() 117 118 err := writeenv(key, value) 119 if err != nil { 120 return err 121 } 122 env[key] = value 123 envs = append(envs, key+"="+value) 124 return nil 125 } 126 127 func Clearenv() { 128 envLock.Lock() 129 defer envLock.Unlock() 130 131 env = make(map[string]string) 132 envs = []string{} 133 RawSyscall(SYS_RFORK, RFCENVG, 0, 0) 134 } 135 136 func Environ() []string { 137 envLock.RLock() 138 defer envLock.RUnlock() 139 140 envOnce.Do(copyenv) 141 return append([]string(nil), envs...) 142 }