diff options
Diffstat (limited to 'libgo/go/internal/syscall/execenv/execenv_windows.go')
-rw-r--r-- | libgo/go/internal/syscall/execenv/execenv_windows.go | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/libgo/go/internal/syscall/execenv/execenv_windows.go b/libgo/go/internal/syscall/execenv/execenv_windows.go new file mode 100644 index 00000000000..b50029c1983 --- /dev/null +++ b/libgo/go/internal/syscall/execenv/execenv_windows.go @@ -0,0 +1,54 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +package execenv + +import ( + "internal/syscall/windows" + "syscall" + "unicode/utf16" + "unsafe" +) + +// Default will return the default environment +// variables based on the process attributes +// provided. +// +// If the process attributes contain a token, then +// the environment variables will be sourced from +// the defaults for that user token, otherwise they +// will be sourced from syscall.Environ(). +func Default(sys *syscall.SysProcAttr) (env []string, err error) { + if sys == nil || sys.Token == 0 { + return syscall.Environ(), nil + } + var block *uint16 + err = windows.CreateEnvironmentBlock(&block, sys.Token, false) + if err != nil { + return nil, err + } + defer windows.DestroyEnvironmentBlock(block) + blockp := uintptr(unsafe.Pointer(block)) + for { + + // find NUL terminator + end := unsafe.Pointer(blockp) + for *(*uint16)(end) != 0 { + end = unsafe.Pointer(uintptr(end) + 2) + } + + n := (uintptr(end) - uintptr(unsafe.Pointer(blockp))) / 2 + if n == 0 { + // environment block ends with empty string + break + } + + entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(blockp))[:n:n] + env = append(env, string(utf16.Decode(entry))) + blockp += 2 * (uintptr(len(entry)) + 1) + } + return +} |