github.com/dorkamotorka/go/src@v0.0.0-20230614113921-187095f0e316/syscall/exec_windows_test.go (about) 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 }