src/pkg/syscall/env_unix.go - The Go Programming Language

Golang

Source file src/pkg/syscall/env_unix.go

     1	// Copyright 2010 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	// +build darwin freebsd linux netbsd openbsd
     6	
     7	// Unix environment variables.
     8	
     9	package syscall
    10	
    11	import "sync"
    12	
    13	var (
    14		// envOnce guards initialization by copyenv, which populates env.
    15		envOnce sync.Once
    16	
    17		// envLock guards env and envs.
    18		envLock sync.RWMutex
    19	
    20		// env maps from an environment variable to its first occurrence in envs.
    21		env map[string]int
    22	
    23		// envs is provided by the runtime. elements are expected to be
    24		// of the form "key=value".
    25		envs []string
    26	)
    27	
    28	// setenv_c is provided by the runtime, but is a no-op if cgo isn't
    29	// loaded.
    30	func setenv_c(k, v string)
    31	
    32	func copyenv() {
    33		env = make(map[string]int)
    34		for i, s := range envs {
    35			for j := 0; j < len(s); j++ {
    36				if s[j] == '=' {
    37					key := s[:j]
    38					if _, ok := env[key]; !ok {
    39						env[key] = i
    40					}
    41					break
    42				}
    43			}
    44		}
    45	}
    46	
    47	func Getenv(key string) (value string, found bool) {
    48		envOnce.Do(copyenv)
    49		if len(key) == 0 {
    50			return "", false
    51		}
    52	
    53		envLock.RLock()
    54		defer envLock.RUnlock()
    55	
    56		i, ok := env[key]
    57		if !ok {
    58			return "", false
    59		}
    60		s := envs[i]
    61		for i := 0; i < len(s); i++ {
    62			if s[i] == '=' {
    63				return s[i+1:], true
    64			}
    65		}
    66		return "", false
    67	}
    68	
    69	func Setenv(key, value string) error {
    70		envOnce.Do(copyenv)
    71		if len(key) == 0 {
    72			return EINVAL
    73		}
    74	
    75		envLock.Lock()
    76		defer envLock.Unlock()
    77	
    78		i, ok := env[key]
    79		kv := key + "=" + value
    80		if ok {
    81			envs[i] = kv
    82		} else {
    83			i = len(envs)
    84			envs = append(envs, kv)
    85		}
    86		env[key] = i
    87		setenv_c(key, value)
    88		return nil
    89	}
    90	
    91	func Clearenv() {
    92		envOnce.Do(copyenv) // prevent copyenv in Getenv/Setenv
    93	
    94		envLock.Lock()
    95		defer envLock.Unlock()
    96	
    97		env = make(map[string]int)
    98		envs = []string{}
    99		// TODO(bradfitz): pass through to C
   100	}
   101	
   102	func Environ() []string {
   103		envOnce.Do(copyenv)
   104		envLock.RLock()
   105		defer envLock.RUnlock()
   106		a := make([]string, len(envs))
   107		copy(a, envs)
   108		return a
   109	}