2018-07-06 08:07:37 +00:00
|
|
|
package main
|
|
|
|
|
2018-07-10 06:48:54 +00:00
|
|
|
import (
|
2018-07-24 09:51:28 +00:00
|
|
|
"fmt"
|
2018-07-10 06:48:54 +00:00
|
|
|
"os"
|
|
|
|
"os/signal"
|
2018-07-24 09:51:28 +00:00
|
|
|
"sync"
|
2018-07-10 22:40:04 +00:00
|
|
|
"syscall"
|
2018-07-10 06:48:54 +00:00
|
|
|
|
|
|
|
"golang.org/x/sys/unix"
|
|
|
|
"novit.nc/direktil/pkg/log"
|
|
|
|
)
|
2018-07-06 08:07:37 +00:00
|
|
|
|
2018-07-24 09:51:28 +00:00
|
|
|
var reapLock = sync.RWMutex{}
|
|
|
|
|
2018-07-06 08:07:37 +00:00
|
|
|
func handleChildren() {
|
2018-07-24 09:51:28 +00:00
|
|
|
sigchld := make(chan os.Signal, 2048)
|
|
|
|
signal.Notify(sigchld, syscall.SIGCHLD)
|
|
|
|
|
2018-07-10 06:48:54 +00:00
|
|
|
// set us as a sub-reaper
|
|
|
|
if err := unix.Prctl(unix.PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0); err != nil {
|
|
|
|
initLog.Taintf(log.Error, "reaper: failed to set myself a child sub-reaper: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for range sigchld {
|
2018-07-10 22:40:04 +00:00
|
|
|
reapChildren()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func reapChildren() {
|
2018-07-24 09:51:28 +00:00
|
|
|
reapLock.Lock()
|
|
|
|
defer reapLock.Unlock()
|
2018-07-10 22:40:04 +00:00
|
|
|
for {
|
|
|
|
pid, err := syscall.Wait4(-1, nil, syscall.WNOHANG, nil)
|
2018-07-24 09:51:28 +00:00
|
|
|
if err != nil && err != syscall.ECHILD {
|
2018-07-10 22:40:04 +00:00
|
|
|
initLog.Taintf(log.Warning, "reaper: wait4 failed: %v", err)
|
2018-07-24 09:51:28 +00:00
|
|
|
fmt.Printf("reaper: wait4 failed: %v\n", err)
|
|
|
|
break
|
2018-07-10 22:40:04 +00:00
|
|
|
}
|
|
|
|
if pid <= 0 {
|
|
|
|
break
|
2018-07-10 06:48:54 +00:00
|
|
|
}
|
|
|
|
}
|
2018-07-06 08:07:37 +00:00
|
|
|
}
|