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 }