The Go Programming Language

Source file src/pkg/os/env_windows.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	// Windows environment variables.
     6	
     7	package os
     8	
     9	import (
    10		"syscall"
    11		"utf16"
    12		"unsafe"
    13	)
    14	
    15	// ENOENV is the Error indicating that an environment variable does not exist.
    16	var ENOENV = NewError("no such environment variable")
    17	
    18	// Getenverror retrieves the value of the environment variable named by the key.
    19	// It returns the value and an error, if any.
    20	func Getenverror(key string) (value string, err Error) {
    21		b := make([]uint16, 100)
    22		n, e := syscall.GetEnvironmentVariable(syscall.StringToUTF16Ptr(key), &b[0], uint32(len(b)))
    23		if n == 0 && e == syscall.ERROR_ENVVAR_NOT_FOUND {
    24			return "", ENOENV
    25		}
    26		if n > uint32(len(b)) {
    27			b = make([]uint16, n)
    28			n, e = syscall.GetEnvironmentVariable(syscall.StringToUTF16Ptr(key), &b[0], uint32(len(b)))
    29			if n > uint32(len(b)) {
    30				n = 0
    31			}
    32		}
    33		if n == 0 {
    34			return "", NewSyscallError("GetEnvironmentVariable", e)
    35		}
    36		return string(utf16.Decode(b[0:n])), nil
    37	}
    38	
    39	// Getenv retrieves the value of the environment variable named by the key.
    40	// It returns the value, which will be empty if the variable is not present.
    41	func Getenv(key string) string {
    42		v, _ := Getenverror(key)
    43		return v
    44	}
    45	
    46	// Setenv sets the value of the environment variable named by the key.
    47	// It returns an Error, if any.
    48	func Setenv(key, value string) Error {
    49		var v *uint16
    50		if len(value) > 0 {
    51			v = syscall.StringToUTF16Ptr(value)
    52		}
    53		e := syscall.SetEnvironmentVariable(syscall.StringToUTF16Ptr(key), v)
    54		if e != 0 {
    55			return NewSyscallError("SetEnvironmentVariable", e)
    56		}
    57		return nil
    58	}
    59	
    60	// Clearenv deletes all environment variables.
    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			// http://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx
    66			for j := 1; j < len(s); j++ {
    67				if s[j] == '=' {
    68					Setenv(s[0:j], "")
    69					break
    70				}
    71			}
    72		}
    73	}
    74	
    75	// Environ returns an array of strings representing the environment,
    76	// in the form "key=value".
    77	func Environ() []string {
    78		s, e := syscall.GetEnvironmentStrings()
    79		if e != 0 {
    80			return nil
    81		}
    82		defer syscall.FreeEnvironmentStrings(s)
    83		r := make([]string, 0, 50) // Empty with room to grow.
    84		for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(s)); true; i++ {
    85			if p[i] == 0 {
    86				// empty string marks the end
    87				if i <= from {
    88					break
    89				}
    90				r = append(r, string(utf16.Decode(p[from:i])))
    91				from = i + 1
    92			}
    93		}
    94		return r
    95	}
    96	
    97	// TempDir returns the default directory to use for temporary files.
    98	func TempDir() string {
    99		const pathSep = '\\'
   100		dirw := make([]uint16, syscall.MAX_PATH)
   101		n, _ := syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
   102		if n > uint32(len(dirw)) {
   103			dirw = make([]uint16, n)
   104			n, _ = syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
   105			if n > uint32(len(dirw)) {
   106				n = 0
   107			}
   108		}
   109		if n > 0 && dirw[n-1] == pathSep {
   110			n--
   111		}
   112		return string(utf16.Decode(dirw[0:n]))
   113	}
   114	
   115	func init() {
   116		var argc int32
   117		cmd := syscall.GetCommandLine()
   118		argv, e := syscall.CommandLineToArgv(cmd, &argc)
   119		if e != 0 {
   120			return
   121		}
   122		defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv))))
   123		Args = make([]string, argc)
   124		for i, v := range (*argv)[:argc] {
   125			Args[i] = string(syscall.UTF16ToString((*v)[:]))
   126		}
   127	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.