mirror of
https://github.com/shirou/gopsutil.git
synced 2025-04-24 13:48:56 +08:00
Merge pull request #1706 from Lomanic/issue1698
[process][darwin][freebsd][linux][openbsd] Make process.Children not reliant on pgrep
This commit is contained in:
commit
e89f21d7dc
@ -40,23 +40,3 @@ func CallLsofWithContext(ctx context.Context, invoke Invoker, pid int32, args ..
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func CallPgrepWithContext(ctx context.Context, invoke Invoker, pid int32) ([]int32, error) {
|
||||
out, err := invoke.CommandWithContext(ctx, "pgrep", "-P", strconv.Itoa(int(pid)))
|
||||
if err != nil {
|
||||
return []int32{}, err
|
||||
}
|
||||
lines := strings.Split(string(out), "\n")
|
||||
ret := make([]int32, 0, len(lines))
|
||||
for _, l := range lines {
|
||||
if len(l) == 0 {
|
||||
continue
|
||||
}
|
||||
i, err := strconv.ParseInt(l, 10, 32)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ret = append(ret, int32(i))
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
|
||||
var (
|
||||
invoke common.Invoker = common.Invoke{}
|
||||
ErrorNoChildren = errors.New("process does not have children")
|
||||
ErrorNoChildren = errors.New("process does not have children") // Deprecated: ErrorNoChildren is never returned by process.Children(), check its returned []*Process slice length instead
|
||||
ErrorProcessNotRunning = errors.New("process does not exist")
|
||||
ErrorNotPermitted = errors.New("operation not permitted")
|
||||
)
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -233,18 +234,21 @@ func convertCPUTimes(s string) (ret float64, err error) {
|
||||
}
|
||||
|
||||
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
|
||||
pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid)
|
||||
procs, err := ProcessesWithContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil
|
||||
}
|
||||
ret := make([]*Process, 0, len(pids))
|
||||
for _, pid := range pids {
|
||||
np, err := NewProcessWithContext(ctx, pid)
|
||||
ret := make([]*Process, 0, len(procs))
|
||||
for _, proc := range procs {
|
||||
ppid, err := proc.PpidWithContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
continue
|
||||
}
|
||||
if ppid == p.Pid {
|
||||
ret = append(ret, proc)
|
||||
}
|
||||
ret = append(ret, np)
|
||||
}
|
||||
sort.Slice(ret, func(i, j int) bool { return ret[i].Pid < ret[j].Pid })
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -269,18 +270,21 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e
|
||||
}
|
||||
|
||||
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
|
||||
pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid)
|
||||
procs, err := ProcessesWithContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil
|
||||
}
|
||||
ret := make([]*Process, 0, len(pids))
|
||||
for _, pid := range pids {
|
||||
np, err := NewProcessWithContext(ctx, pid)
|
||||
ret := make([]*Process, 0, len(procs))
|
||||
for _, proc := range procs {
|
||||
ppid, err := proc.PpidWithContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
continue
|
||||
}
|
||||
if ppid == p.Pid {
|
||||
ret = append(ret, proc)
|
||||
}
|
||||
ret = append(ret, np)
|
||||
}
|
||||
sort.Slice(ret, func(i, j int) bool { return ret[i].Pid < ret[j].Pid })
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -338,21 +339,34 @@ func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, e
|
||||
}
|
||||
|
||||
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
|
||||
pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid)
|
||||
statFiles, err := filepath.Glob(common.HostProcWithContext(ctx, "[0-9]*/stat"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(pids) == 0 {
|
||||
return nil, ErrorNoChildren
|
||||
}
|
||||
ret := make([]*Process, 0, len(pids))
|
||||
for _, pid := range pids {
|
||||
np, err := NewProcessWithContext(ctx, pid)
|
||||
ret := make([]*Process, 0, len(statFiles))
|
||||
for _, statFile := range statFiles {
|
||||
statContents, err := os.ReadFile(statFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
continue
|
||||
}
|
||||
fields := splitProcStat(statContents)
|
||||
pid, err := strconv.ParseInt(fields[1], 10, 32)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ppid, err := strconv.ParseInt(fields[4], 10, 32)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if int32(ppid) == p.Pid {
|
||||
np, err := NewProcessWithContext(ctx, int32(pid))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ret = append(ret, np)
|
||||
}
|
||||
ret = append(ret, np)
|
||||
}
|
||||
sort.Slice(ret, func(i, j int) bool { return ret[i].Pid < ret[j].Pid })
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
@ -286,18 +287,21 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e
|
||||
}
|
||||
|
||||
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
|
||||
pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid)
|
||||
procs, err := ProcessesWithContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil
|
||||
}
|
||||
ret := make([]*Process, 0, len(pids))
|
||||
for _, pid := range pids {
|
||||
np, err := NewProcessWithContext(ctx, pid)
|
||||
ret := make([]*Process, 0, len(procs))
|
||||
for _, proc := range procs {
|
||||
ppid, err := proc.PpidWithContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
continue
|
||||
}
|
||||
if ppid == p.Pid {
|
||||
ret = append(ret, proc)
|
||||
}
|
||||
ret = append(ret, np)
|
||||
}
|
||||
sort.Slice(ret, func(i, j int) bool { return ret[i].Pid < ret[j].Pid })
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user