| | |
| | |
| | |
| |
|
| | |
| | |
| |
|
| | package main |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | import "C" |
| |
|
| | import ( |
| | "fmt" |
| | "io/fs" |
| | "os" |
| | "os/exec" |
| | "os/signal" |
| | "sync" |
| | "syscall" |
| | ) |
| |
|
| | func init() { |
| | register("CgoExecSignalMask", CgoExecSignalMask) |
| | } |
| |
|
| | func CgoExecSignalMask() { |
| | if len(os.Args) > 2 && os.Args[2] == "testsigint" { |
| | if C.SIGINTBlocked() != 0 { |
| | os.Exit(1) |
| | } |
| | os.Exit(0) |
| | } |
| |
|
| | c := make(chan os.Signal, 1) |
| | signal.Notify(c, syscall.SIGTERM) |
| | go func() { |
| | for range c { |
| | } |
| | }() |
| |
|
| | const goCount = 10 |
| | const execCount = 10 |
| | var wg sync.WaitGroup |
| | wg.Add(goCount*execCount + goCount) |
| | for i := 0; i < goCount; i++ { |
| | go func() { |
| | defer wg.Done() |
| | for j := 0; j < execCount; j++ { |
| | c2 := make(chan os.Signal, 1) |
| | signal.Notify(c2, syscall.SIGUSR1) |
| | syscall.Kill(os.Getpid(), syscall.SIGTERM) |
| | go func(j int) { |
| | defer wg.Done() |
| | cmd := exec.Command(os.Args[0], "CgoExecSignalMask", "testsigint") |
| | cmd.Stdin = os.Stdin |
| | cmd.Stdout = os.Stdout |
| | cmd.Stderr = os.Stderr |
| | if err := cmd.Run(); err != nil { |
| | |
| | |
| | |
| | |
| | |
| | if isEAGAIN(err) { |
| | return |
| | } |
| | fmt.Printf("iteration %d: %v\n", j, err) |
| | os.Exit(1) |
| | } |
| | }(j) |
| | signal.Stop(c2) |
| | } |
| | }() |
| | } |
| | wg.Wait() |
| |
|
| | fmt.Println("OK") |
| | } |
| |
|
| | |
| | func isEAGAIN(err error) bool { |
| | if p, ok := err.(*fs.PathError); ok { |
| | err = p.Err |
| | } |
| | return err == syscall.EAGAIN |
| | } |
| |
|