1
2
3
4
5
6
7
8 package main
9
10
31 import "C"
32
33 import (
34 "fmt"
35 "io/fs"
36 "os"
37 "os/exec"
38 "os/signal"
39 "sync"
40 "syscall"
41 )
42
43 func init() {
44 register("CgoExecSignalMask", CgoExecSignalMask)
45 }
46
47 func CgoExecSignalMask() {
48 if len(os.Args) > 2 && os.Args[2] == "testsigint" {
49 if C.SIGINTBlocked() != 0 {
50 os.Exit(1)
51 }
52 os.Exit(0)
53 }
54
55 c := make(chan os.Signal, 1)
56 signal.Notify(c, syscall.SIGTERM)
57 go func() {
58 for range c {
59 }
60 }()
61
62 const goCount = 10
63 const execCount = 10
64 var wg sync.WaitGroup
65 wg.Add(goCount*execCount + goCount)
66 for i := 0; i < goCount; i++ {
67 go func() {
68 defer wg.Done()
69 for j := 0; j < execCount; j++ {
70 c2 := make(chan os.Signal, 1)
71 signal.Notify(c2, syscall.SIGUSR1)
72 syscall.Kill(os.Getpid(), syscall.SIGTERM)
73 go func(j int) {
74 defer wg.Done()
75 cmd := exec.Command(os.Args[0], "CgoExecSignalMask", "testsigint")
76 cmd.Stdin = os.Stdin
77 cmd.Stdout = os.Stdout
78 cmd.Stderr = os.Stderr
79 if err := cmd.Run(); err != nil {
80
81
82
83
84
85 if isEAGAIN(err) {
86 return
87 }
88 fmt.Printf("iteration %d: %v\n", j, err)
89 os.Exit(1)
90 }
91 }(j)
92 signal.Stop(c2)
93 }
94 }()
95 }
96 wg.Wait()
97
98 fmt.Println("OK")
99 }
100
101
102 func isEAGAIN(err error) bool {
103 if p, ok := err.(*fs.PathError); ok {
104 err = p.Err
105 }
106 return err == syscall.EAGAIN
107 }
108
View as plain text