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