Source file
src/os/signal/signal_windows_test.go
1
2
3
4
5 package signal
6
7 import (
8 "bytes"
9 "internal/testenv"
10 "os"
11 "os/exec"
12 "path/filepath"
13 "syscall"
14 "testing"
15 "time"
16 )
17
18 func sendCtrlBreak(t *testing.T, pid int) {
19 d, e := syscall.LoadDLL("kernel32.dll")
20 if e != nil {
21 t.Fatalf("LoadDLL: %v\n", e)
22 }
23 p, e := d.FindProc("GenerateConsoleCtrlEvent")
24 if e != nil {
25 t.Fatalf("FindProc: %v\n", e)
26 }
27 r, _, e := p.Call(syscall.CTRL_BREAK_EVENT, uintptr(pid))
28 if r == 0 {
29 t.Fatalf("GenerateConsoleCtrlEvent: %v\n", e)
30 }
31 }
32
33 func TestCtrlBreak(t *testing.T) {
34
35 const source = `
36 package main
37
38 import (
39 "log"
40 "os"
41 "os/signal"
42 "time"
43 )
44
45
46 func main() {
47 c := make(chan os.Signal, 10)
48 signal.Notify(c)
49 select {
50 case s := <-c:
51 if s != os.Interrupt {
52 log.Fatalf("Wrong signal received: got %q, want %q\n", s, os.Interrupt)
53 }
54 case <-time.After(3 * time.Second):
55 log.Fatalf("Timeout waiting for Ctrl+Break\n")
56 }
57 }
58 `
59 tmp := t.TempDir()
60
61
62 name := filepath.Join(tmp, "ctlbreak")
63 src := name + ".go"
64 f, err := os.Create(src)
65 if err != nil {
66 t.Fatalf("Failed to create %v: %v", src, err)
67 }
68 defer f.Close()
69 f.Write([]byte(source))
70
71
72 exe := name + ".exe"
73 defer os.Remove(exe)
74 o, err := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, src).CombinedOutput()
75 if err != nil {
76 t.Fatalf("Failed to compile: %v\n%v", err, string(o))
77 }
78
79
80 cmd := exec.Command(exe)
81 var b bytes.Buffer
82 cmd.Stdout = &b
83 cmd.Stderr = &b
84 cmd.SysProcAttr = &syscall.SysProcAttr{
85 CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
86 }
87 err = cmd.Start()
88 if err != nil {
89 t.Fatalf("Start failed: %v", err)
90 }
91 go func() {
92 time.Sleep(1 * time.Second)
93 sendCtrlBreak(t, cmd.Process.Pid)
94 }()
95 err = cmd.Wait()
96 if err != nil {
97 t.Fatalf("Program exited with error: %v\n%v", err, string(b.Bytes()))
98 }
99 }
100
View as plain text