Terminate owned subprocess trees
This commit is contained in:
50
internal/adapters/subprocess/process_tree_unix.go
Normal file
50
internal/adapters/subprocess/process_tree_unix.go
Normal file
@@ -0,0 +1,50 @@
|
||||
//go:build linux || darwin
|
||||
|
||||
package subprocess
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type unixProcessTree struct {
|
||||
processGroupID int
|
||||
}
|
||||
|
||||
func newOwnedProcessTree() (ownedProcessTree, error) {
|
||||
return &unixProcessTree{}, nil
|
||||
}
|
||||
|
||||
func (tree *unixProcessTree) Start(cmd *exec.Cmd) error {
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
if err := cmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
tree.processGroupID = cmd.Process.Pid
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tree *unixProcessTree) TerminateGracefully() error {
|
||||
return tree.signal(syscall.SIGTERM)
|
||||
}
|
||||
|
||||
func (tree *unixProcessTree) TerminateForcefully() error {
|
||||
return tree.signal(syscall.SIGKILL)
|
||||
}
|
||||
|
||||
func (tree *unixProcessTree) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tree *unixProcessTree) signal(signal syscall.Signal) error {
|
||||
if tree.processGroupID <= 0 {
|
||||
return nil
|
||||
}
|
||||
err := syscall.Kill(-tree.processGroupID, signal)
|
||||
if errors.Is(err, syscall.ESRCH) || errors.Is(err, os.ErrProcessDone) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user