Home | History | Annotate | Download | only in testprogcgo
      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 }
     90