github.com/c12o16h1/go/src@v0.0.0-20200114212001-5a151c0f00ed/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  )
    12  
    13  var (
    14  	errZeroLengthKey = errors.New("zero length key")
    15  	errShortWrite    = errors.New("i/o count too small")
    16  )
    17  
    18  func readenv(key string) (string, error) {
    19  	fd, err := open("/env/"+key, O_RDONLY)
    20  	if err != nil {
    21  		return "", err
    22  	}
    23  	defer Close(fd)
    24  	l, _ := Seek(fd, 0, 2)
    25  	Seek(fd, 0, 0)
    26  	buf := make([]byte, l)
    27  	n, err := Read(fd, buf)
    28  	if err != nil {
    29  		return "", err
    30  	}
    31  	if n > 0 && buf[n-1] == 0 {
    32  		buf = buf[:n-1]
    33  	}
    34  	return string(buf), nil
    35  }
    36  
    37  func writeenv(key, value string) error {
    38  	fd, err := create("/env/"+key, O_RDWR, 0666)
    39  	if err != nil {
    40  		return err
    41  	}
    42  	defer Close(fd)
    43  	b := []byte(value)
    44  	n, err := Write(fd, b)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	if n != len(b) {
    49  		return errShortWrite
    50  	}
    51  	return nil
    52  }
    53  
    54  func Getenv(key string) (value string, found bool) {
    55  	if len(key) == 0 {
    56  		return "", false
    57  	}
    58  	v, err := readenv(key)
    59  	if err != nil {
    60  		return "", false
    61  	}
    62  	return v, true
    63  }
    64  
    65  func Setenv(key, value string) error {
    66  	if len(key) == 0 {
    67  		return errZeroLengthKey
    68  	}
    69  	err := writeenv(key, value)
    70  	if err != nil {
    71  		return err
    72  	}
    73  	return nil
    74  }
    75  
    76  func Clearenv() {
    77  	// Creating a new environment group using rfork(RFCENVG) can race
    78  	// with access to files in /env (e.g. from Setenv or Getenv).
    79  	// Remove all environment variables in current environment group instead.
    80  	fd, err := open("/env", O_RDONLY)
    81  	if err != nil {
    82  		return
    83  	}
    84  	defer Close(fd)
    85  	files, err := readdirnames(fd)
    86  	if err != nil {
    87  		return
    88  	}
    89  	for _, key := range files {
    90  		Remove("/env/" + key)
    91  	}
    92  }
    93  
    94  func Unsetenv(key string) error {
    95  	if len(key) == 0 {
    96  		return errZeroLengthKey
    97  	}
    98  	Remove("/env/" + key)
    99  	return nil
   100  }
   101  
   102  func Environ() []string {
   103  	fd, err := open("/env", O_RDONLY)
   104  	if err != nil {
   105  		return nil
   106  	}
   107  	defer Close(fd)
   108  	files, err := readdirnames(fd)
   109  	if err != nil {
   110  		return nil
   111  	}
   112  	ret := make([]string, 0, len(files))
   113  
   114  	for _, key := range files {
   115  		v, err := readenv(key)
   116  		if err != nil {
   117  			continue
   118  		}
   119  		ret = append(ret, key+"="+v)
   120  	}
   121  	return ret
   122  }