env_windows.mx raw

   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  // Windows environment variables.
   6  
   7  package syscall
   8  
   9  import (
  10  	"unsafe"
  11  )
  12  
  13  func Getenv(key string) (value string, found bool) {
  14  	keyp, err := UTF16PtrFromString(key)
  15  	if err != nil {
  16  		return "", false
  17  	}
  18  	n := uint32(100)
  19  	for {
  20  		b := make([]uint16, n)
  21  		n, err = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
  22  		if n == 0 && err == ERROR_ENVVAR_NOT_FOUND {
  23  			return "", false
  24  		}
  25  		if n <= uint32(len(b)) {
  26  			return UTF16ToString(b[:n]), true
  27  		}
  28  	}
  29  }
  30  
  31  func Setenv(key, value string) error {
  32  	v, err := UTF16PtrFromString(value)
  33  	if err != nil {
  34  		return err
  35  	}
  36  	keyp, err := UTF16PtrFromString(key)
  37  	if err != nil {
  38  		return err
  39  	}
  40  	e := SetEnvironmentVariable(keyp, v)
  41  	if e != nil {
  42  		return e
  43  	}
  44  	runtimeSetenv(key, value)
  45  	return nil
  46  }
  47  
  48  func Unsetenv(key string) error {
  49  	keyp, err := UTF16PtrFromString(key)
  50  	if err != nil {
  51  		return err
  52  	}
  53  	e := SetEnvironmentVariable(keyp, nil)
  54  	if e != nil {
  55  		return e
  56  	}
  57  	runtimeUnsetenv(key)
  58  	return nil
  59  }
  60  
  61  func Clearenv() {
  62  	for _, s := range Environ() {
  63  		// Environment variables can begin with =
  64  		// so start looking for the separator = at j=1.
  65  		// https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133
  66  		for j := 1; j < len(s); j++ {
  67  			if s[j] == '=' {
  68  				Unsetenv(s[0:j])
  69  				break
  70  			}
  71  		}
  72  	}
  73  }
  74  
  75  func Environ() []string {
  76  	envp, e := GetEnvironmentStrings()
  77  	if e != nil {
  78  		return nil
  79  	}
  80  	defer FreeEnvironmentStrings(envp)
  81  
  82  	r := make([]string, 0, 50) // Empty with room to grow.
  83  	const size = unsafe.Sizeof(*envp)
  84  	for *envp != 0 { // environment block ends with empty string
  85  		// find NUL terminator
  86  		end := unsafe.Pointer(envp)
  87  		for *(*uint16)(end) != 0 {
  88  			end = unsafe.Add(end, size)
  89  		}
  90  
  91  		entry := unsafe.Slice(envp, (uintptr(end)-uintptr(unsafe.Pointer(envp)))/size)
  92  		r = append(r, UTF16ToString(entry))
  93  		envp = (*uint16)(unsafe.Add(end, size))
  94  	}
  95  	return r
  96  }
  97