Home | History | Annotate | Download | only in syscall
      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 	RawSyscall(SYS_RFORK, RFCENVG, 0, 0)
     78 }
     79 
     80 func Unsetenv(key string) error {
     81 	if len(key) == 0 {
     82 		return errZeroLengthKey
     83 	}
     84 	Remove("/env/" + key)
     85 	return nil
     86 }
     87 
     88 func Environ() []string {
     89 	fd, err := open("/env", O_RDONLY)
     90 	if err != nil {
     91 		return nil
     92 	}
     93 	defer Close(fd)
     94 	files, err := readdirnames(fd)
     95 	if err != nil {
     96 		return nil
     97 	}
     98 	ret := make([]string, 0, len(files))
     99 
    100 	for _, key := range files {
    101 		v, err := readenv(key)
    102 		if err != nil {
    103 			continue
    104 		}
    105 		ret = append(ret, key+"="+v)
    106 	}
    107 	return ret
    108 }
    109