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
63
64
65
66
67
68
69
70
71
72
73
74
//go:build linux || darwin
package devsup
import (
"encoding/json"
"os"
"path/filepath"
"syscall"
)
func SweepOffline(state string) ([]SweepReport, error) {
entries, err := filepath.Glob(filepath.Join(state, "units", "*.json"))
if err != nil {
return nil, err
}
var table []ProcEntry
for _, p := range procTable() {
table = append(table, ProcEntry{PID: p.pid, PGID: p.pgid, Ticks: p.ticks})
}
var out []SweepReport
for _, path := range entries {
var rec Record
b, err := os.ReadFile(path)
if err == nil {
err = json.Unmarshal(b, &rec)
}
if err != nil {
continue
}
v := SweepDecision(rec, table)
if v == SweepGroup {
syscall.Kill(-rec.PGID, syscall.SIGKILL)
}
if rec.Devsup != "" {
for pid, a := range attributedTo(rec.Devsup) {
if a.unit == rec.Spec.Name {
syscall.Kill(pid, syscall.SIGKILL)
}
}
}
out = append(out, SweepReport{Unit: rec.Spec.Name, PGID: rec.PGID, Verdict: v.String()})
os.Remove(path)
}
return out, nil
}
func InstanceProcesses(instance string) []int {
var out []int
for _, p := range procTable() {
if procEnv(p.pid, EnvInstance)[EnvInstance] == instance && p.pid != os.Getpid() {
out = append(out, p.pid)
}
}
return out
}
func KillInstance(instance string) []int {
pids := InstanceProcesses(instance)
for _, pid := range pids {
syscall.Kill(pid, syscall.SIGKILL)
}
return pids
}
func Alive(pid int) bool {
p, ok := readProcInfo(pid)
return ok && p.state != 'Z' && p.state != 'X'
}
func Exists(pid int) bool {
_, ok := readProcInfo(pid)
return ok
}