github.com/s1s1ty/go@v0.0.0-20180207192209-104445e3140f/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  }