1
0
mirror of https://github.com/shirou/gopsutil.git synced 2025-04-24 13:48:56 +08:00
Lomanic 76ccf0d220 [process][darwin][freebsd][linux][openbsd] Make process.Children not reliant on pgrep
pgrep -P $PID exits with status of 1 (and nothing in stdout nor stderr) both if
a process doesn't exist or it doesn't have child processes, so we don't
use it anymore on these OSes. We sort PIDs as pgrep did.

Also deprecate the ErrorNoChildren error when there are no child processes,
this is erroneous (simply check for the length of the returned slice, plus
this is not an error per se), this was only returned on linux anyway.

Fixes #1698
2024-09-10 15:34:36 +02:00

43 lines
939 B
Go

// SPDX-License-Identifier: BSD-3-Clause
//go:build linux || freebsd || darwin || openbsd
package common
import (
"context"
"errors"
"os/exec"
"strconv"
"strings"
)
func CallLsofWithContext(ctx context.Context, invoke Invoker, pid int32, args ...string) ([]string, error) {
var cmd []string
if pid == 0 { // will get from all processes.
cmd = []string{"-a", "-n", "-P"}
} else {
cmd = []string{"-a", "-n", "-P", "-p", strconv.Itoa(int(pid))}
}
cmd = append(cmd, args...)
out, err := invoke.CommandWithContext(ctx, "lsof", cmd...)
if err != nil {
if errors.Is(err, exec.ErrNotFound) {
return []string{}, err
}
// if no pid found, lsof returns code 1.
if err.Error() == "exit status 1" && len(out) == 0 {
return []string{}, nil
}
}
lines := strings.Split(string(out), "\n")
var ret []string
for _, l := range lines[1:] {
if len(l) == 0 {
continue
}
ret = append(ret, l)
}
return ret, nil
}