Source file
src/syscall/exec_windows_test.go
1
2
3
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
53
54
55 time.Sleep(time.Minute)
56 os.Exit(0)
57 }
58
59 if os.Getenv("GO_WANT_HELPER_PROCESS") == "child" {
60
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
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
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