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  }