From 13b619cef7a670a0312110c24b12819149237de9 Mon Sep 17 00:00:00 2001 From: Konstantin Pereiaslov Date: Sat, 28 Sep 2024 03:24:46 -0500 Subject: [PATCH] Start services in a separate process group and use process groups for killing them, to kill the child processes too. --- main.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/main.go b/main.go index 55f6dd8..f1f4425 100644 --- a/main.go +++ b/main.go @@ -515,6 +515,10 @@ func runServiceCommand(serviceConfig ServiceConfig) *exec.Cmd { serviceConfig.Workdir, ) cmd := exec.Command(serviceConfig.Command, strings.Split(serviceConfig.Args, " ")...) + cmd.SysProcAttr = &syscall.SysProcAttr{ + Setpgid: true, + Pgid: 0, + } if serviceConfig.Workdir != "" { cmd.Dir = serviceConfig.Workdir } @@ -562,17 +566,17 @@ func stopService(serviceName string) { runningService.idleTimer.Stop() } if runningService.cmd != nil && runningService.cmd.Process != nil { - log.Printf("[%s] Sending SIGTERM to service process: %d", serviceName, runningService.cmd.Process.Pid) - err := runningService.cmd.Process.Signal(syscall.SIGTERM) + log.Printf("[%s] Sending SIGTERM to service process group: -%d", serviceName, runningService.cmd.Process.Pid) + err := syscall.Kill(-runningService.cmd.Process.Pid, syscall.SIGTERM) if err != nil { - log.Printf("[%s] Failed to send SIGTERM to %d: %v", serviceName, runningService.cmd.Process.Pid, err) + log.Printf("[%s] Failed to send SIGTERM to -%d: %v", serviceName, runningService.cmd.Process.Pid, err) } processExitedCleanly := waitForProcessToTerminate(runningService.cmd.Process) if !processExitedCleanly { - log.Printf("[%s] Timed out waiting, sending SIGKILL to service process %d", serviceName, runningService.cmd.Process.Pid) - err := runningService.cmd.Process.Kill() + log.Printf("[%s] Timed out waiting, sending SIGKILL to service process group -%d", serviceName, runningService.cmd.Process.Pid) + err := syscall.Kill(-runningService.cmd.Process.Pid, syscall.SIGKILL) if err != nil { log.Printf("[%s] Failed to kill service: %v", serviceName, err) if runningService.cmd.ProcessState == nil {