scobleclaw/pkg/floxenv/alive.go
agent-cos 163a3333d3 feat(pkg/floxenv): add Flox environment lifecycle management package
- 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
2026-05-29 23:40:22 -07:00

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)
}