Home | History | Annotate | Download | only in syscall
      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 	"unicode/utf16"
     11 	"unsafe"
     12 )
     13 
     14 func Getenv(key string) (value string, found bool) {
     15 	keyp, err := UTF16PtrFromString(key)
     16 	if err != nil {
     17 		return "", false
     18 	}
     19 	n := uint32(100)
     20 	for {
     21 		b := make([]uint16, n)
     22 		n, err = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
     23 		if n == 0 && err == ERROR_ENVVAR_NOT_FOUND {
     24 			return "", false
     25 		}
     26 		if n <= uint32(len(b)) {
     27 			return string(utf16.Decode(b[:n])), true
     28 		}
     29 	}
     30 }
     31 
     32 func Setenv(key, value string) error {
     33 	v, err := UTF16PtrFromString(value)
     34 	if err != nil {
     35 		return err
     36 	}
     37 	keyp, err := UTF16PtrFromString(key)
     38 	if err != nil {
     39 		return err
     40 	}
     41 	e := SetEnvironmentVariable(keyp, v)
     42 	if e != nil {
     43 		return e
     44 	}
     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 	return SetEnvironmentVariable(keyp, nil)
     54 }
     55 
     56 func Clearenv() {
     57 	for _, s := range Environ() {
     58 		// Environment variables can begin with =
     59 		// so start looking for the separator = at j=1.
     60 		// http://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx
     61 		for j := 1; j < len(s); j++ {
     62 			if s[j] == '=' {
     63 				Unsetenv(s[0:j])
     64 				break
     65 			}
     66 		}
     67 	}
     68 }
     69 
     70 func Environ() []string {
     71 	s, e := GetEnvironmentStrings()
     72 	if e != nil {
     73 		return nil
     74 	}
     75 	defer FreeEnvironmentStrings(s)
     76 	r := make([]string, 0, 50) // Empty with room to grow.
     77 	for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(s)); true; i++ {
     78 		if p[i] == 0 {
     79 			// empty string marks the end
     80 			if i <= from {
     81 				break
     82 			}
     83 			r = append(r, string(utf16.Decode(p[from:i])))
     84 			from = i + 1
     85 		}
     86 	}
     87 	return r
     88 }
     89