github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/os/env_windows.go (about)

     1  // Copyright 2019 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  package os
     6  
     7  import (
     8  	"github.com/x04/go/src/internal/syscall/windows"
     9  	"github.com/x04/go/src/syscall"
    10  	"github.com/x04/go/src/unicode/utf16"
    11  	"github.com/x04/go/src/unsafe"
    12  )
    13  
    14  func environForSysProcAttr(sys *syscall.SysProcAttr) (env []string, err error) {
    15  	if sys == nil || sys.Token == 0 {
    16  		return Environ(), nil
    17  	}
    18  	var block *uint16
    19  	err = windows.CreateEnvironmentBlock(&block, sys.Token, false)
    20  	if err != nil {
    21  		return nil, err
    22  	}
    23  	defer windows.DestroyEnvironmentBlock(block)
    24  	blockp := uintptr(unsafe.Pointer(block))
    25  	for {
    26  
    27  		// find NUL terminator
    28  		end := unsafe.Pointer(blockp)
    29  		for *(*uint16)(end) != 0 {
    30  			end = unsafe.Pointer(uintptr(end) + 2)
    31  		}
    32  
    33  		n := (uintptr(end) - uintptr(unsafe.Pointer(blockp))) / 2
    34  		if n == 0 {
    35  			// environment block ends with empty string
    36  			break
    37  		}
    38  
    39  		entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(blockp))[:n:n]
    40  		env = append(env, string(utf16.Decode(entry)))
    41  		blockp += 2 * (uintptr(len(entry)) + 1)
    42  	}
    43  	return
    44  }