Files
Privatae e4c9b69b46
ci / personal-data (push) Successful in 5s
ci / test (push) Successful in 3m4s
ci / fuzz (push) Successful in 3m45s
bastion 0.53.2
2026-10-20 04:42:14 +00:00

72 lines
2.0 KiB
Go

//go:build darwin
package main
import (
"strconv"
"strings"
)
// macOS facts for the origin walk: one `ps` sweep with pid, ppid, tty and
// `comm`. "??" is no terminal.
//
// `comm` on macOS is argv[0] — usually a full path, because launchd and dyld
// exec with one, but chosen by the launcher all the same (Apple's ps maps the
// comm keyword to just_command, adv_cmds ps/keyword.c:101, which skips the
// kernel's saved exec_path to reach argv[0]). This file once said it was the
// kernel's path. Good enough to match the launchd inventory
// below; never an identity — procExe (agents_darwin.go) is that.
// No unit: launchd's label for a pid is a per-pid `launchctl procinfo`,
// too costly for a beat; interval jobs are recognised instead by matching
// the executable against the launchd inventory (originExtra.ScheduledExes).
func parsePSFacts(out string) map[int]procFacts {
m := map[int]procFacts{}
for _, line := range strings.Split(out, "\n") {
f := strings.Fields(line)
if len(f) < 4 {
continue
}
pid, err := strconv.Atoi(f[0])
if err != nil || pid <= 0 {
continue
}
ppid, _ := strconv.Atoi(f[1])
exe := strings.Join(f[3:], " ")
pf := procFacts{PID: pid, PPID: ppid, Comm: binBase(exe), Exe: exe}
if f[2] != "??" && f[2] != "-" {
pf.Interactive, pf.Detail = true, "tty "+f[2]
}
m[pid] = pf
}
return m
}
func procFactsReader() func(int) (procFacts, bool) {
var facts map[int]procFacts
return func(pid int) (procFacts, bool) {
if facts == nil {
facts = map[int]procFacts{}
if out, err := runTimed("ps", "-axo", "pid=,ppid=,tty=,comm="); err == nil {
facts = parsePSFacts(string(out))
}
}
f, ok := facts[pid]
return f, ok
}
}
func originExtras() originExtra {
exes := map[string]string{}
entries, _ := scanSchedulers()
for _, e := range entries {
if e.Kind != "launchd" || e.Schedule == "" {
continue
}
if argv := strings.Fields(e.Command); len(argv) > 0 {
exes[strings.ToLower(argv[0])] = e.Name
}
}
return originExtra{ScheduledExes: exes}
}