diff options
Diffstat (limited to '')
-rw-r--r-- | src/syscall/exec_windows_test.go | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/syscall/exec_windows_test.go b/src/syscall/exec_windows_test.go new file mode 100644 index 0000000..8b8f330 --- /dev/null +++ b/src/syscall/exec_windows_test.go @@ -0,0 +1,115 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package syscall_test + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "syscall" + "testing" + "time" +) + +func TestEscapeArg(t *testing.T) { + var tests = []struct { + input, output string + }{ + {``, `""`}, + {`a`, `a`}, + {` `, `" "`}, + {`\`, `\`}, + {`"`, `\"`}, + {`\"`, `\\\"`}, + {`\\"`, `\\\\\"`}, + {`\\ `, `"\\ "`}, + {` \\`, `" \\\\"`}, + {`a `, `"a "`}, + {`C:\`, `C:\`}, + {`C:\Program Files (x32)\Common\`, `"C:\Program Files (x32)\Common\\"`}, + {`C:\Users\Игорь\`, `C:\Users\Игорь\`}, + {`Андрей\file`, `Андрей\file`}, + {`C:\Windows\temp`, `C:\Windows\temp`}, + {`c:\temp\newfile`, `c:\temp\newfile`}, + {`\\?\C:\Windows`, `\\?\C:\Windows`}, + {`\\?\`, `\\?\`}, + {`\\.\C:\Windows\`, `\\.\C:\Windows\`}, + {`\\server\share\file`, `\\server\share\file`}, + {`\\newserver\tempshare\really.txt`, `\\newserver\tempshare\really.txt`}, + } + for _, test := range tests { + if got := syscall.EscapeArg(test.input); got != test.output { + t.Errorf("EscapeArg(%#q) = %#q, want %#q", test.input, got, test.output) + } + } +} + +func TestChangingProcessParent(t *testing.T) { + if os.Getenv("GO_WANT_HELPER_PROCESS") == "parent" { + // in parent process + + // Parent does nothing. It is just used as a parent of a child process. + time.Sleep(time.Minute) + os.Exit(0) + } + + if os.Getenv("GO_WANT_HELPER_PROCESS") == "child" { + // in child process + dumpPath := os.Getenv("GO_WANT_HELPER_PROCESS_FILE") + if dumpPath == "" { + fmt.Fprintf(os.Stderr, "Dump file path cannot be blank.") + os.Exit(1) + } + err := os.WriteFile(dumpPath, []byte(fmt.Sprintf("%d", os.Getppid())), 0644) + if err != nil { + fmt.Fprintf(os.Stderr, "Error writing dump file: %v", err) + os.Exit(2) + } + os.Exit(0) + } + + // run parent process + + parent := exec.Command(os.Args[0], "-test.run=TestChangingProcessParent") + parent.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=parent") + err := parent.Start() + if err != nil { + t.Fatal(err) + } + defer func() { + parent.Process.Kill() + parent.Wait() + }() + + // run child process + + const _PROCESS_CREATE_PROCESS = 0x0080 + const _PROCESS_DUP_HANDLE = 0x0040 + childDumpPath := filepath.Join(t.TempDir(), "ppid.txt") + ph, err := syscall.OpenProcess(_PROCESS_CREATE_PROCESS|_PROCESS_DUP_HANDLE|syscall.PROCESS_QUERY_INFORMATION, + false, uint32(parent.Process.Pid)) + if err != nil { + t.Fatal(err) + } + defer syscall.CloseHandle(ph) + + child := exec.Command(os.Args[0], "-test.run=TestChangingProcessParent") + child.Env = append(os.Environ(), + "GO_WANT_HELPER_PROCESS=child", + "GO_WANT_HELPER_PROCESS_FILE="+childDumpPath) + child.SysProcAttr = &syscall.SysProcAttr{ParentProcess: ph} + childOutput, err := child.CombinedOutput() + if err != nil { + t.Errorf("child failed: %v: %v", err, string(childOutput)) + } + childOutput, err = os.ReadFile(childDumpPath) + if err != nil { + t.Fatalf("reading child output failed: %v", err) + } + if got, want := string(childOutput), fmt.Sprintf("%d", parent.Process.Pid); got != want { + t.Fatalf("child output: want %q, got %q", want, got) + } +} |