// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd
// This is in testprognet instead of testprog because testprog
// must not import anything (like net, but also like os/signal)
// that kicks off background goroutines during init.
package main
import (
"fmt"
"os"
"os/exec"
"os/signal"
"sync"
"syscall"
"time"
)
func init() {
register("SignalDuringExec", SignalDuringExec)
register("Nop", Nop)
}
func SignalDuringExec() {
pgrp := syscall.Getpgrp()
const tries = 10
var wg sync.WaitGroup
c := make(chan os.Signal, tries)
signal.Notify(c, syscall.SIGWINCH)
wg.Add(1)
go func() {
defer wg.Done()
for range c {
}
}()
for i := 0; i < tries; i++ {
time.Sleep(time.Microsecond)
wg.Add(2)
go func() {
defer wg.Done()
cmd := exec.Command(os.Args[0], "Nop")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Printf("Start failed: %v", err)
}
}()
go func() {
defer wg.Done()
syscall.Kill(-pgrp, syscall.SIGWINCH)
}()
}
signal.Stop(c)
close(c)
wg.Wait()
fmt.Println("OK")
}
func Nop() {
// This is just for SignalDuringExec.
}
|