mirror of
https://github.com/patriceckhart/zot.git
synced 2026-06-26 21:36:31 +02:00
Fix telegram bot process checks on Windows
This commit is contained in:
parent
7f954ceaa3
commit
798174c22c
3 changed files with 101 additions and 33 deletions
|
|
@ -7,7 +7,6 @@ import (
|
|||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -68,42 +67,15 @@ func IsRunning(zotHome string) (int, bool, error) {
|
|||
if pid <= 0 {
|
||||
return 0, false, nil
|
||||
}
|
||||
proc, err := os.FindProcess(pid)
|
||||
alive, err := processAlive(pid)
|
||||
if err != nil {
|
||||
return pid, false, nil
|
||||
}
|
||||
// signal 0 is POSIX's "does the process exist?" probe. On Windows
|
||||
// os.Process is always usable and Signal(0) returns nil, so we'd
|
||||
// miss stale pids; acceptable for the macos/linux-first audience.
|
||||
if err := proc.Signal(syscall.Signal(0)); err != nil {
|
||||
if errors.Is(err, os.ErrProcessDone) || errors.Is(err, syscall.ESRCH) {
|
||||
return pid, false, nil
|
||||
}
|
||||
// Other errors (EPERM) mean the process exists but we can't
|
||||
// inspect it; treat as running.
|
||||
return pid, true, nil
|
||||
}
|
||||
return pid, true, nil
|
||||
return pid, alive, nil
|
||||
}
|
||||
|
||||
// StopProcess sends SIGTERM to pid and waits up to graceful for it to
|
||||
// exit, then escalates to SIGKILL. Returns nil if the process is gone.
|
||||
// StopProcess asks pid to exit and waits up to graceful for it to stop,
|
||||
// then escalates to a forced kill. Returns nil if the process is gone.
|
||||
func StopProcess(pid int, graceful time.Duration) error {
|
||||
proc, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = proc.Signal(syscall.SIGTERM)
|
||||
|
||||
deadline := time.Now().Add(graceful)
|
||||
for time.Now().Before(deadline) {
|
||||
if err := proc.Signal(syscall.Signal(0)); err != nil {
|
||||
if errors.Is(err, os.ErrProcessDone) || errors.Is(err, syscall.ESRCH) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
_ = proc.Kill()
|
||||
return nil
|
||||
return stopProcess(pid, graceful)
|
||||
}
|
||||
|
|
|
|||
44
packages/agent/modes/telegram/process_unix.go
Normal file
44
packages/agent/modes/telegram/process_unix.go
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
//go:build !windows
|
||||
|
||||
package telegram
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func processAlive(pid int) (bool, error) {
|
||||
proc, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := proc.Signal(syscall.Signal(0)); err != nil {
|
||||
if errors.Is(err, os.ErrProcessDone) || errors.Is(err, syscall.ESRCH) {
|
||||
return false, nil
|
||||
}
|
||||
// Other errors (EPERM) mean the process exists but we can't inspect it.
|
||||
return true, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func stopProcess(pid int, graceful time.Duration) error {
|
||||
proc, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = proc.Signal(syscall.SIGTERM)
|
||||
|
||||
deadline := time.Now().Add(graceful)
|
||||
for time.Now().Before(deadline) {
|
||||
alive, err := processAlive(pid)
|
||||
if err != nil || !alive {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
_ = proc.Kill()
|
||||
return nil
|
||||
}
|
||||
52
packages/agent/modes/telegram/process_windows.go
Normal file
52
packages/agent/modes/telegram/process_windows.go
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
//go:build windows
|
||||
|
||||
package telegram
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const stillActive = 259
|
||||
|
||||
func processAlive(pid int) (bool, error) {
|
||||
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
|
||||
if err != nil {
|
||||
if errors.Is(err, windows.ERROR_INVALID_PARAMETER) {
|
||||
return false, nil
|
||||
}
|
||||
if errors.Is(err, windows.ERROR_ACCESS_DENIED) {
|
||||
return true, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
defer windows.CloseHandle(h)
|
||||
|
||||
var code uint32
|
||||
if err := windows.GetExitCodeProcess(h, &code); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return code == stillActive, nil
|
||||
}
|
||||
|
||||
func stopProcess(pid int, graceful time.Duration) error {
|
||||
proc, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = proc.Signal(os.Interrupt)
|
||||
|
||||
deadline := time.Now().Add(graceful)
|
||||
for time.Now().Before(deadline) {
|
||||
alive, err := processAlive(pid)
|
||||
if err != nil || !alive {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
_ = proc.Kill()
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue