mirror of
https://github.com/shirou/gopsutil.git
synced 2025-04-24 13:48:56 +08:00

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
43 lines
939 B
Go
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
|
|
}
|