40 lines
1.0 KiB
Go
40 lines
1.0 KiB
Go
//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
|
|
}
|
|
}
|