Source file src/os/exec/exec_windows_test.go

     1  // Copyright 2021 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  //go:build windows
     6  
     7  package exec_test
     8  
     9  import (
    10  	"fmt"
    11  	"internal/testenv"
    12  	"io"
    13  	"os"
    14  	"os/exec"
    15  	"strconv"
    16  	"strings"
    17  	"syscall"
    18  	"testing"
    19  )
    20  
    21  var (
    22  	quitSignal os.Signal = nil
    23  	pipeSignal os.Signal = syscall.SIGPIPE
    24  )
    25  
    26  func init() {
    27  	registerHelperCommand("pipehandle", cmdPipeHandle)
    28  }
    29  
    30  func cmdPipeHandle(args ...string) {
    31  	handle, _ := strconv.ParseUint(args[0], 16, 64)
    32  	pipe := os.NewFile(uintptr(handle), "")
    33  	_, err := fmt.Fprint(pipe, args[1])
    34  	if err != nil {
    35  		fmt.Fprintf(os.Stderr, "writing to pipe failed: %v\n", err)
    36  		os.Exit(1)
    37  	}
    38  	pipe.Close()
    39  }
    40  
    41  func TestPipePassing(t *testing.T) {
    42  	t.Parallel()
    43  
    44  	r, w, err := os.Pipe()
    45  	if err != nil {
    46  		t.Error(err)
    47  	}
    48  	const marker = "arrakis, dune, desert planet"
    49  	childProc := helperCommand(t, "pipehandle", strconv.FormatUint(uint64(w.Fd()), 16), marker)
    50  	childProc.SysProcAttr = &syscall.SysProcAttr{AdditionalInheritedHandles: []syscall.Handle{syscall.Handle(w.Fd())}}
    51  	err = childProc.Start()
    52  	if err != nil {
    53  		t.Error(err)
    54  	}
    55  	w.Close()
    56  	response, err := io.ReadAll(r)
    57  	if err != nil {
    58  		t.Error(err)
    59  	}
    60  	r.Close()
    61  	if string(response) != marker {
    62  		t.Errorf("got %q; want %q", string(response), marker)
    63  	}
    64  	err = childProc.Wait()
    65  	if err != nil {
    66  		t.Error(err)
    67  	}
    68  }
    69  
    70  func TestNoInheritHandles(t *testing.T) {
    71  	t.Parallel()
    72  
    73  	cmd := testenv.Command(t, "cmd", "/c exit 88")
    74  	cmd.SysProcAttr = &syscall.SysProcAttr{NoInheritHandles: true}
    75  	err := cmd.Run()
    76  	exitError, ok := err.(*exec.ExitError)
    77  	if !ok {
    78  		t.Fatalf("got error %v; want ExitError", err)
    79  	}
    80  	if exitError.ExitCode() != 88 {
    81  		t.Fatalf("got exit code %d; want 88", exitError.ExitCode())
    82  	}
    83  }
    84  
    85  // start a child process without the user code explicitly starting
    86  // with a copy of the parent's SYSTEMROOT.
    87  // (See issue 25210.)
    88  func TestChildCriticalEnv(t *testing.T) {
    89  	t.Parallel()
    90  	cmd := helperCommand(t, "echoenv", "SYSTEMROOT")
    91  
    92  	// Explicitly remove SYSTEMROOT from the command's environment.
    93  	var env []string
    94  	for _, kv := range cmd.Environ() {
    95  		k, _, ok := strings.Cut(kv, "=")
    96  		if !ok || !strings.EqualFold(k, "SYSTEMROOT") {
    97  			env = append(env, kv)
    98  		}
    99  	}
   100  	cmd.Env = env
   101  
   102  	out, err := cmd.CombinedOutput()
   103  	if err != nil {
   104  		t.Fatal(err)
   105  	}
   106  	if strings.TrimSpace(string(out)) == "" {
   107  		t.Error("no SYSTEMROOT found")
   108  	}
   109  }
   110  

View as plain text