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