~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
74 lines · 1.5 KB Raw History
//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
}