chore: sync from fn-registry agent
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const procMaxEntries = 200
|
||||
|
||||
// runProcList enumera procesos. En linux usa /proc parsing via `ps -eo`.
|
||||
func runProcList(cap *Capability, args map[string]any) (any, int, error) {
|
||||
_ = cap
|
||||
_ = args
|
||||
if runtime.GOOS == "windows" {
|
||||
return runProcListWindows()
|
||||
}
|
||||
return runProcListUnix()
|
||||
}
|
||||
|
||||
func runProcListUnix() (any, int, error) {
|
||||
if _, err := exec.LookPath("ps"); err != nil {
|
||||
return nil, -1, fmt.Errorf("ps binary not found")
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
// ps -eo pid,ppid,user,comm,rss,pcpu --no-headers
|
||||
c := exec.CommandContext(ctx, "ps", "-eo", "pid,ppid,user,comm,rss,pcpu", "--no-headers")
|
||||
out, err := c.Output()
|
||||
if err != nil {
|
||||
return nil, -1, fmt.Errorf("ps: %w", err)
|
||||
}
|
||||
lines := strings.Split(string(out), "\n")
|
||||
processes := []map[string]any{}
|
||||
for _, line := range lines {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) < 6 {
|
||||
continue
|
||||
}
|
||||
pid, _ := strconv.Atoi(fields[0])
|
||||
ppid, _ := strconv.Atoi(fields[1])
|
||||
user := fields[2]
|
||||
name := fields[3]
|
||||
rss, _ := strconv.ParseInt(fields[4], 10, 64)
|
||||
cpu, _ := strconv.ParseFloat(fields[5], 64)
|
||||
processes = append(processes, map[string]any{
|
||||
"pid": pid,
|
||||
"ppid": ppid,
|
||||
"user": user,
|
||||
"name": name,
|
||||
"rss_kb": rss,
|
||||
"cpu_pct": cpu,
|
||||
})
|
||||
if len(processes) >= procMaxEntries {
|
||||
break
|
||||
}
|
||||
}
|
||||
return map[string]any{
|
||||
"processes": processes,
|
||||
"count": len(processes),
|
||||
"truncated": len(processes) >= procMaxEntries,
|
||||
}, 0, nil
|
||||
}
|
||||
|
||||
func runProcListWindows() (any, int, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
c := exec.CommandContext(ctx, "tasklist", "/FO", "CSV", "/NH")
|
||||
out, err := c.Output()
|
||||
if err != nil {
|
||||
return nil, -1, fmt.Errorf("tasklist: %w", err)
|
||||
}
|
||||
lines := strings.Split(string(out), "\n")
|
||||
processes := []map[string]any{}
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
parts := strings.Split(line, ",")
|
||||
if len(parts) < 5 {
|
||||
continue
|
||||
}
|
||||
name := strings.Trim(parts[0], `"`)
|
||||
pid, _ := strconv.Atoi(strings.Trim(parts[1], `"`))
|
||||
processes = append(processes, map[string]any{
|
||||
"pid": pid,
|
||||
"name": name,
|
||||
})
|
||||
if len(processes) >= procMaxEntries {
|
||||
break
|
||||
}
|
||||
}
|
||||
return map[string]any{
|
||||
"processes": processes,
|
||||
"count": len(processes),
|
||||
"truncated": len(processes) >= procMaxEntries,
|
||||
}, 0, nil
|
||||
}
|
||||
Reference in New Issue
Block a user