File size: 1,548 Bytes
6a7089a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | //go:build windows
package orchestrator
import (
"os"
"os/exec"
"syscall"
"unsafe"
)
func setProcGroup(cmd *exec.Cmd) {}
func killProcessGroup(pid int, _ syscall.Signal) error {
p, err := os.FindProcess(pid)
if err != nil {
return err
}
return p.Kill()
}
var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
procOpenProcess = modkernel32.NewProc("OpenProcess")
procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess")
)
const (
processQueryLimitedInfo = 0x1000
stillActive = 259 // STATUS_PENDING — process has not exited
)
func processAlive(pid int) bool {
// On Windows, os.Process.Signal(0) always fails because Go does not
// support signals on Windows (only os.Kill via TerminateProcess).
// Instead, use OpenProcess + GetExitCodeProcess to check liveness.
handle, _, err := procOpenProcess.Call(
uintptr(processQueryLimitedInfo),
0, // bInheritHandle = false
uintptr(pid),
)
if handle == 0 {
// Cannot open process — either it doesn't exist or access denied.
// If access denied the process is alive, but we can't tell; assume dead
// to match the previous (broken) behaviour conservatively.
_ = err
return false
}
defer func() { _ = syscall.CloseHandle(syscall.Handle(handle)) }()
var exitCode uint32
ret, _, _ := procGetExitCodeProcess.Call(handle, uintptr(unsafe.Pointer(&exitCode)))
if ret == 0 {
return false // API call failed
}
return exitCode == stillActive
}
const sigTERM = syscall.Signal(0xf)
const sigKILL = syscall.Signal(0x9)
|