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