- Activate / Deactivate via flox activate --detach (with graceful SIGTERM→SIGKILL) - Non-privileged IsAlive process check with Linux /proc fallback - Dev-mode stub when flox is missing or FLOXENV_DEV_MODE=1 - Unit and integration tests Closes #16
46 lines
1 KiB
Go
46 lines
1 KiB
Go
package floxenv
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
)
|
|
|
|
// IsAlive returns true if the process identified by pid is still running.
|
|
// It first attempts a zero-signal delivery test, then confirms on Linux
|
|
// by inspecting /proc/<pid>/stat so that zombie processes are reported dead.
|
|
func IsAlive(pid int) bool {
|
|
if pid <= 0 {
|
|
return false
|
|
}
|
|
if err := syscall.Kill(pid, 0); err != nil {
|
|
return false
|
|
}
|
|
// Linux-specific confirmation to distinguish zombies.
|
|
data, err := os.ReadFile(fmt.Sprintf("/proc/%d/stat", pid))
|
|
if err != nil {
|
|
// /proc may be unavailable in restricted spaces; trust signal result.
|
|
return true
|
|
}
|
|
s := string(data)
|
|
idx := strings.LastIndexByte(s, ')')
|
|
if idx >= 0 && idx+2 < len(s) {
|
|
state := s[idx+2]
|
|
if state == 'Z' { // zombie
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// IsAliveString wraps IsAlive with string-to-int conversion.
|
|
// It returns false for any parse or signal error.
|
|
func IsAliveString(s string) bool {
|
|
pid, err := strconv.Atoi(s)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return IsAlive(pid)
|
|
}
|