master
go 44 lines 812 Bytes
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 //go:build !windows
4
5 package ndexec
6
7 import (
8 "errors"
9 "os"
10 "os/exec"
11 "syscall"
12 "time"
13 )
14
15 func configureCommandCancellation(cmd *exec.Cmd) {
16 if cmd == nil {
17 return
18 }
19
20 if cmd.SysProcAttr == nil {
21 cmd.SysProcAttr = &syscall.SysProcAttr{}
22 }
23 cmd.SysProcAttr.Setpgid = true
24 cmd.WaitDelay = 250 * time.Millisecond
25 cmd.Cancel = func() error {
26 if cmd.Process == nil {
27 return nil
28 }
29 if err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL); err != nil && !errors.Is(err, syscall.ESRCH) {
30 return resolveDirectKillFallback(cmd.Process.Kill())
31 }
32 return nil
33 }
34 }
35
36 func resolveDirectKillFallback(killErr error) error {
37 if killErr == nil {
38 return nil
39 }
40 if errors.Is(killErr, os.ErrProcessDone) {
41 return os.ErrProcessDone
42 }
43 return killErr
44 }