| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- // Copyright 2011 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- // Plan 9 environment variables.
- package plan9
- import (
- "errors"
- "sync"
- )
- var (
- // envOnce guards copyenv, which populates env.
- envOnce sync.Once
- // envLock guards env and envs.
- envLock sync.RWMutex
- // env maps from an environment variable to its value.
- env = make(map[string]string)
- // envs contains elements of env in the form "key=value".
- envs []string
- errZeroLengthKey = errors.New("zero length key")
- errShortWrite = errors.New("i/o count too small")
- )
- func readenv(key string) (string, error) {
- fd, err := Open("/env/"+key, O_RDONLY)
- if err != nil {
- return "", err
- }
- defer Close(fd)
- l, _ := Seek(fd, 0, 2)
- Seek(fd, 0, 0)
- buf := make([]byte, l)
- n, err := Read(fd, buf)
- if err != nil {
- return "", err
- }
- if n > 0 && buf[n-1] == 0 {
- buf = buf[:n-1]
- }
- return string(buf), nil
- }
- func writeenv(key, value string) error {
- fd, err := Create("/env/"+key, O_RDWR, 0666)
- if err != nil {
- return err
- }
- defer Close(fd)
- b := []byte(value)
- n, err := Write(fd, b)
- if err != nil {
- return err
- }
- if n != len(b) {
- return errShortWrite
- }
- return nil
- }
- func copyenv() {
- fd, err := Open("/env", O_RDONLY)
- if err != nil {
- return
- }
- defer Close(fd)
- files, err := readdirnames(fd)
- if err != nil {
- return
- }
- envs = make([]string, len(files))
- i := 0
- for _, key := range files {
- v, err := readenv(key)
- if err != nil {
- continue
- }
- env[key] = v
- envs[i] = key + "=" + v
- i++
- }
- }
- func Getenv(key string) (value string, found bool) {
- if len(key) == 0 {
- return "", false
- }
- envLock.RLock()
- defer envLock.RUnlock()
- if v, ok := env[key]; ok {
- return v, true
- }
- v, err := readenv(key)
- if err != nil {
- return "", false
- }
- env[key] = v
- envs = append(envs, key+"="+v)
- return v, true
- }
- func Setenv(key, value string) error {
- if len(key) == 0 {
- return errZeroLengthKey
- }
- envLock.Lock()
- defer envLock.Unlock()
- err := writeenv(key, value)
- if err != nil {
- return err
- }
- env[key] = value
- envs = append(envs, key+"="+value)
- return nil
- }
- func Clearenv() {
- envLock.Lock()
- defer envLock.Unlock()
- env = make(map[string]string)
- envs = []string{}
- RawSyscall(SYS_RFORK, RFCENVG, 0, 0)
- }
- func Environ() []string {
- envLock.RLock()
- defer envLock.RUnlock()
- envOnce.Do(copyenv)
- return append([]string(nil), envs...)
- }
|