|
|
|
@ -3,44 +3,26 @@
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"log"
|
|
|
|
|
"os"
|
|
|
|
|
"os/signal"
|
|
|
|
|
"syscall"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
|
go reapChildren()
|
|
|
|
|
go watchChildSignal()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func childSignal(notify chan bool) {
|
|
|
|
|
func watchChildSignal() {
|
|
|
|
|
var sigs = make(chan os.Signal, 3)
|
|
|
|
|
signal.Notify(sigs, syscall.SIGCHLD)
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
<-sigs
|
|
|
|
|
select {
|
|
|
|
|
case notify <- true:
|
|
|
|
|
default:
|
|
|
|
|
// Channel full, does not matter as we wait for all children.
|
|
|
|
|
}
|
|
|
|
|
reapChildren()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func reapChildren() {
|
|
|
|
|
var wstatus syscall.WaitStatus
|
|
|
|
|
notify := make(chan bool, 1)
|
|
|
|
|
|
|
|
|
|
go childSignal(notify)
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
pid, err := syscall.Wait4(-1, &wstatus, 0, nil)
|
|
|
|
|
for err == syscall.EINTR {
|
|
|
|
|
pid, err = syscall.Wait4(-1, &wstatus, 0, nil)
|
|
|
|
|
}
|
|
|
|
|
if err == syscall.ECHILD {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
log.Printf("pid %d, finished, wstatus: %+v", pid, wstatus)
|
|
|
|
|
}
|
|
|
|
|
syscall.Wait4(-1, &wstatus, syscall.WNOHANG, nil)
|
|
|
|
|
}
|
|
|
|
|