//go:build !windows package windsurf import ( "os" "os/exec" "syscall" "time" ) // attachProcessGroup configures the child to run in its own process group so // we can signal the entire tree on shutdown. Windows has no Unix-style // process groups; see lspool_stop_windows.go for the no-op. func attachProcessGroup(cmd *exec.Cmd) { if cmd.SysProcAttr == nil { cmd.SysProcAttr = &syscall.SysProcAttr{} } cmd.SysProcAttr.Setpgid = true } // terminateProcess asks the LS process (and its children) to exit // gracefully, then kills them if they don't exit within 5 seconds. func terminateProcess(p *os.Process, done <-chan struct{}) { pgid, err := syscall.Getpgid(p.Pid) if err != nil { // Process may have already exited; fall back to signalling // the original PID directly. pgid = p.Pid } // Negative pid here means "send to the whole process group" per kill(2). _ = syscall.Kill(-pgid, syscall.SIGINT) select { case <-done: case <-time.After(5 * time.Second): _ = syscall.Kill(-pgid, syscall.SIGKILL) <-done } }