mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
a90d8d35ee
isProcessRunning() previously only checked whether a PID existed via signal(0)/OpenProcess, without confirming the process was actually picoclaw. When the PID was reused by an unrelated process (e.g., systemd-resolved after a kill -9), the gateway would refuse to start with 'already running'. Add isPicoclawProcess() that verifies the process name matches picoclaw: - Unix: reads /proc/<pid>/comm - Windows: calls QueryFullProcessImageNameW If the running process is not picoclaw, treat the PID file as stale and proceed with normal startup. Falls back to trusting the liveness check when identity verification is unavailable (e.g., /proc unreadable, API call fails). Fixes #2720.
75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
//go:build windows
|
|
|
|
package pid
|
|
|
|
import (
|
|
"strings"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
var (
|
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
procOpenProcess = kernel32.NewProc("OpenProcess")
|
|
procGetExitCodeProcess = kernel32.NewProc("GetExitCodeProcess")
|
|
procCloseHandle = kernel32.NewProc("CloseHandle")
|
|
procQueryFullProcessImageNameW = kernel32.NewProc("QueryFullProcessImageNameW")
|
|
processQueryLimitedInformation = uint32(0x1000)
|
|
stillActive = uint32(259)
|
|
)
|
|
|
|
// isProcessRunning checks whether a process with the given PID is alive
|
|
// on Windows using OpenProcess + GetExitCodeProcess.
|
|
func isProcessRunning(pid int) bool {
|
|
if pid <= 0 {
|
|
return false
|
|
}
|
|
|
|
handle, _, _ := procOpenProcess.Call(
|
|
uintptr(processQueryLimitedInformation),
|
|
0,
|
|
uintptr(pid),
|
|
)
|
|
if handle == 0 {
|
|
return false
|
|
}
|
|
defer procCloseHandle.Call(handle)
|
|
|
|
var exitCode uint32
|
|
ret, _, _ := procGetExitCodeProcess.Call(handle, uintptr(unsafe.Pointer(&exitCode)))
|
|
if ret == 0 {
|
|
return false
|
|
}
|
|
return exitCode == stillActive
|
|
}
|
|
|
|
// isPicoclawProcess uses QueryFullProcessImageNameW to confirm the
|
|
// process image name contains "picoclaw". Returns false when the name
|
|
// clearly does not match. Returns true if the query fails, falling
|
|
// back to trusting the liveness check alone.
|
|
func isPicoclawProcess(pid int) bool {
|
|
handle, _, _ := procOpenProcess.Call(
|
|
uintptr(processQueryLimitedInformation),
|
|
0,
|
|
uintptr(pid),
|
|
)
|
|
if handle == 0 {
|
|
return true // cannot open — trust liveness check
|
|
}
|
|
defer procCloseHandle.Call(handle)
|
|
|
|
var buf [260]uint16
|
|
var size uint32 = 260
|
|
ret, _, _ := procQueryFullProcessImageNameW.Call(
|
|
uintptr(handle),
|
|
0, // WIN32_NAME_FORMAT
|
|
uintptr(unsafe.Pointer(&buf[0])),
|
|
uintptr(unsafe.Pointer(&size)),
|
|
)
|
|
if ret == 0 {
|
|
return true // cannot verify — trust liveness check
|
|
}
|
|
name := strings.ToLower(syscall.UTF16ToString(buf[:size]))
|
|
return strings.Contains(name, "picoclaw")
|
|
}
|