Source file src/runtime/testdata/testprognet/signalexec.go

     1  // Copyright 2017 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  //go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
     6  // +build darwin dragonfly freebsd linux netbsd openbsd
     7  
     8  // This is in testprognet instead of testprog because testprog
     9  // must not import anything (like net, but also like os/signal)
    10  // that kicks off background goroutines during init.
    11  
    12  package main
    13  
    14  import (
    15  	"fmt"
    16  	"os"
    17  	"os/exec"
    18  	"os/signal"
    19  	"sync"
    20  	"syscall"
    21  	"time"
    22  )
    23  
    24  func init() {
    25  	register("SignalDuringExec", SignalDuringExec)
    26  	register("Nop", Nop)
    27  }
    28  
    29  func SignalDuringExec() {
    30  	pgrp := syscall.Getpgrp()
    31  
    32  	const tries = 10
    33  
    34  	var wg sync.WaitGroup
    35  	c := make(chan os.Signal, tries)
    36  	signal.Notify(c, syscall.SIGWINCH)
    37  	wg.Add(1)
    38  	go func() {
    39  		defer wg.Done()
    40  		for range c {
    41  		}
    42  	}()
    43  
    44  	for i := 0; i < tries; i++ {
    45  		time.Sleep(time.Microsecond)
    46  		wg.Add(2)
    47  		go func() {
    48  			defer wg.Done()
    49  			cmd := exec.Command(os.Args[0], "Nop")
    50  			cmd.Stdout = os.Stdout
    51  			cmd.Stderr = os.Stderr
    52  			if err := cmd.Run(); err != nil {
    53  				fmt.Printf("Start failed: %v", err)
    54  			}
    55  		}()
    56  		go func() {
    57  			defer wg.Done()
    58  			syscall.Kill(-pgrp, syscall.SIGWINCH)
    59  		}()
    60  	}
    61  
    62  	signal.Stop(c)
    63  	close(c)
    64  	wg.Wait()
    65  
    66  	fmt.Println("OK")
    67  }
    68  
    69  func Nop() {
    70  	// This is just for SignalDuringExec.
    71  }
    72  

View as plain text