// +build integration package boot import ( "log" "os" "syscall" "time" ) // durationMin returns the smaller of two given durations func durationMin(a, b time.Duration) time.Duration { if a < b { return a } return b } // killProcessCleanly firstly sends SIGTERM to the process. If it still exists // after the specified timeout, it sends SIGKILL func killProcessCleanly(process *os.Process, timeout time.Duration) error { err := process.Signal(syscall.SIGTERM) if err != nil { log.Printf("cannot send SIGTERM to process, sending SIGKILL instead: %v", err) return process.Kill() } const pollInterval = 10 * time.Millisecond for { p, err := os.FindProcess(process.Pid) if err != nil { return nil } err = p.Signal(syscall.Signal(0)) if err != nil { return nil } sleep := durationMin(pollInterval, timeout) if sleep == 0 { break } timeout -= sleep time.Sleep(sleep) } return process.Kill() }