github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/runtime/testdata/testprogcgo/exec.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build !plan9,!windows 6 7 package main 8 9 /* 10 #include <stddef.h> 11 #include <signal.h> 12 #include <pthread.h> 13 14 // Save the signal mask at startup so that we see what it is before 15 // the Go runtime starts setting up signals. 16 17 static sigset_t mask; 18 19 static void init(void) __attribute__ ((constructor)); 20 21 static void init() { 22 sigemptyset(&mask); 23 pthread_sigmask(SIG_SETMASK, NULL, &mask); 24 } 25 26 int SIGINTBlocked() { 27 return sigismember(&mask, SIGINT); 28 } 29 */ 30 import "C" 31 32 import ( 33 "fmt" 34 "os" 35 "os/exec" 36 "os/signal" 37 "sync" 38 "syscall" 39 ) 40 41 func init() { 42 register("CgoExecSignalMask", CgoExecSignalMask) 43 } 44 45 func CgoExecSignalMask() { 46 if len(os.Args) > 2 && os.Args[2] == "testsigint" { 47 if C.SIGINTBlocked() != 0 { 48 os.Exit(1) 49 } 50 os.Exit(0) 51 } 52 53 c := make(chan os.Signal, 1) 54 signal.Notify(c, syscall.SIGTERM) 55 go func() { 56 for range c { 57 } 58 }() 59 60 const goCount = 10 61 const execCount = 10 62 var wg sync.WaitGroup 63 wg.Add(goCount*execCount + goCount) 64 for i := 0; i < goCount; i++ { 65 go func() { 66 defer wg.Done() 67 for j := 0; j < execCount; j++ { 68 c2 := make(chan os.Signal, 1) 69 signal.Notify(c2, syscall.SIGUSR1) 70 syscall.Kill(os.Getpid(), syscall.SIGTERM) 71 go func(j int) { 72 defer wg.Done() 73 cmd := exec.Command(os.Args[0], "CgoExecSignalMask", "testsigint") 74 cmd.Stdin = os.Stdin 75 cmd.Stdout = os.Stdout 76 cmd.Stderr = os.Stderr 77 if err := cmd.Run(); err != nil { 78 fmt.Printf("iteration %d: %v\n", j, err) 79 os.Exit(1) 80 } 81 }(j) 82 signal.Stop(c2) 83 } 84 }() 85 } 86 wg.Wait() 87 88 fmt.Println("OK") 89 }