Source file src/syscall/exec_windows_test.go

     1  // Copyright 2020 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 syscall_test
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"os/exec"
    11  	"path/filepath"
    12  	"syscall"
    13  	"testing"
    14  	"time"
    15  )
    16  
    17  func TestEscapeArg(t *testing.T) {
    18  	var tests = []struct {
    19  		input, output string
    20  	}{
    21  		{``, `""`},
    22  		{`a`, `a`},
    23  		{` `, `" "`},
    24  		{`\`, `\`},
    25  		{`"`, `\"`},
    26  		{`\"`, `\\\"`},
    27  		{`\\"`, `\\\\\"`},
    28  		{`\\ `, `"\\ "`},
    29  		{` \\`, `" \\\\"`},
    30  		{`a `, `"a "`},
    31  		{`C:\`, `C:\`},
    32  		{`C:\Program Files (x32)\Common\`, `"C:\Program Files (x32)\Common\\"`},
    33  		{`C:\Users\Игорь\`, `C:\Users\Игорь\`},
    34  		{`Андрей\file`, `Андрей\file`},
    35  		{`C:\Windows\temp`, `C:\Windows\temp`},
    36  		{`c:\temp\newfile`, `c:\temp\newfile`},
    37  		{`\\?\C:\Windows`, `\\?\C:\Windows`},
    38  		{`\\?\`, `\\?\`},
    39  		{`\\.\C:\Windows\`, `\\.\C:\Windows\`},
    40  		{`\\server\share\file`, `\\server\share\file`},
    41  		{`\\newserver\tempshare\really.txt`, `\\newserver\tempshare\really.txt`},
    42  	}
    43  	for _, test := range tests {
    44  		if got := syscall.EscapeArg(test.input); got != test.output {
    45  			t.Errorf("EscapeArg(%#q) = %#q, want %#q", test.input, got, test.output)
    46  		}
    47  	}
    48  }
    49  
    50  func TestChangingProcessParent(t *testing.T) {
    51  	if os.Getenv("GO_WANT_HELPER_PROCESS") == "parent" {
    52  		// in parent process
    53  
    54  		// Parent does nothing. It is just used as a parent of a child process.
    55  		time.Sleep(time.Minute)
    56  		os.Exit(0)
    57  	}
    58  
    59  	if os.Getenv("GO_WANT_HELPER_PROCESS") == "child" {
    60  		// in child process
    61  		dumpPath := os.Getenv("GO_WANT_HELPER_PROCESS_FILE")
    62  		if dumpPath == "" {
    63  			fmt.Fprintf(os.Stderr, "Dump file path cannot be blank.")
    64  			os.Exit(1)
    65  		}
    66  		err := os.WriteFile(dumpPath, []byte(fmt.Sprintf("%d", os.Getppid())), 0644)
    67  		if err != nil {
    68  			fmt.Fprintf(os.Stderr, "Error writing dump file: %v", err)
    69  			os.Exit(2)
    70  		}
    71  		os.Exit(0)
    72  	}
    73  
    74  	// run parent process
    75  
    76  	parent := exec.Command(os.Args[0], "-test.run=TestChangingProcessParent")
    77  	parent.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=parent")
    78  	err := parent.Start()
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  	defer func() {
    83  		parent.Process.Kill()
    84  		parent.Wait()
    85  	}()
    86  
    87  	// run child process
    88  
    89  	const _PROCESS_CREATE_PROCESS = 0x0080
    90  	const _PROCESS_DUP_HANDLE = 0x0040
    91  	childDumpPath := filepath.Join(t.TempDir(), "ppid.txt")
    92  	ph, err := syscall.OpenProcess(_PROCESS_CREATE_PROCESS|_PROCESS_DUP_HANDLE|syscall.PROCESS_QUERY_INFORMATION,
    93  		false, uint32(parent.Process.Pid))
    94  	if err != nil {
    95  		t.Fatal(err)
    96  	}
    97  	defer syscall.CloseHandle(ph)
    98  
    99  	child := exec.Command(os.Args[0], "-test.run=TestChangingProcessParent")
   100  	child.Env = append(os.Environ(),
   101  		"GO_WANT_HELPER_PROCESS=child",
   102  		"GO_WANT_HELPER_PROCESS_FILE="+childDumpPath)
   103  	child.SysProcAttr = &syscall.SysProcAttr{ParentProcess: ph}
   104  	childOutput, err := child.CombinedOutput()
   105  	if err != nil {
   106  		t.Errorf("child failed: %v: %v", err, string(childOutput))
   107  	}
   108  	childOutput, err = os.ReadFile(childDumpPath)
   109  	if err != nil {
   110  		t.Fatalf("reading child output failed: %v", err)
   111  	}
   112  	if got, want := string(childOutput), fmt.Sprintf("%d", parent.Process.Pid); got != want {
   113  		t.Fatalf("child output: want %q, got %q", want, got)
   114  	}
   115  }
   116  

View as plain text