mirror of
https://github.com/shirou/gopsutil.git
synced 2025-04-29 13:49:21 +08:00
Avoid ps command and use KProc on MacOS
This commit is contained in:
parent
1ccce7b91c
commit
b9b3dbe67a
2
go.mod
2
go.mod
@ -9,5 +9,5 @@ require (
|
|||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/tklauser/go-sysconf v0.3.9
|
github.com/tklauser/go-sysconf v0.3.9
|
||||||
github.com/yusufpapurcu/wmi v1.2.2
|
github.com/yusufpapurcu/wmi v1.2.2
|
||||||
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c
|
golang.org/x/sys v0.0.0-20220111092808-5a964db01320
|
||||||
)
|
)
|
||||||
|
4
go.sum
4
go.sum
@ -26,8 +26,8 @@ github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ
|
|||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c h1:taxlMj0D/1sOAuv/CbSD+MMDof2vbyPTqz5FNYKpXt8=
|
golang.org/x/sys v0.0.0-20220111092808-5a964db01320 h1:0jf+tOCoZ3LyutmCOWpVni1chK4VfFLhRsDK7MhqGRY=
|
||||||
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/v3/cpu"
|
"github.com/shirou/gopsutil/v3/cpu"
|
||||||
"github.com/shirou/gopsutil/v3/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
@ -46,34 +45,25 @@ type _Ctype_struct___0 struct {
|
|||||||
func pidsWithContext(ctx context.Context) ([]int32, error) {
|
func pidsWithContext(ctx context.Context) ([]int32, error) {
|
||||||
var ret []int32
|
var ret []int32
|
||||||
|
|
||||||
pids, err := callPsWithContext(ctx, "pid", 0, false, false)
|
kprocs, err := unix.SysctlKinfoProcSlice("kern.proc.all")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pid := range pids {
|
for _, proc := range kprocs {
|
||||||
v, err := strconv.Atoi(pid[0])
|
ret = append(ret, int32(proc.Proc.P_pid))
|
||||||
if err != nil {
|
|
||||||
return ret, err
|
|
||||||
}
|
|
||||||
ret = append(ret, int32(v))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
|
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
|
||||||
r, err := callPsWithContext(ctx, "ppid", p.Pid, false, false)
|
k, err := p.getKProc()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
v, err := strconv.Atoi(r[0][0])
|
return k.Eproc.Ppid, nil
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return int32(v), err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
||||||
@ -81,7 +71,8 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
name := common.IntToString(k.Proc.P_comm[:])
|
|
||||||
|
name := common.ByteToString(k.Proc.P_comm[:])
|
||||||
|
|
||||||
if len(name) >= 15 {
|
if len(name) >= 15 {
|
||||||
cmdName, err := p.cmdNameWithContext(ctx)
|
cmdName, err := p.cmdNameWithContext(ctx)
|
||||||
@ -111,51 +102,21 @@ func (p *Process) cmdNameWithContext(ctx context.Context) ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
|
func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
|
||||||
r, err := callPsWithContext(ctx, "etime", p.Pid, false, false)
|
k, err := p.getKProc()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
elapsedSegments := strings.Split(strings.Replace(r[0][0], "-", ":", 1), ":")
|
return k.Proc.P_starttime.Sec*1000 + int64(k.Proc.P_starttime.Usec)/1000, nil
|
||||||
var elapsedDurations []time.Duration
|
|
||||||
for i := len(elapsedSegments) - 1; i >= 0; i-- {
|
|
||||||
p, err := strconv.ParseInt(elapsedSegments[i], 10, 0)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
elapsedDurations = append(elapsedDurations, time.Duration(p))
|
|
||||||
}
|
|
||||||
|
|
||||||
elapsed := time.Duration(elapsedDurations[0]) * time.Second
|
|
||||||
if len(elapsedDurations) > 1 {
|
|
||||||
elapsed += time.Duration(elapsedDurations[1]) * time.Minute
|
|
||||||
}
|
|
||||||
if len(elapsedDurations) > 2 {
|
|
||||||
elapsed += time.Duration(elapsedDurations[2]) * time.Hour
|
|
||||||
}
|
|
||||||
if len(elapsedDurations) > 3 {
|
|
||||||
elapsed += time.Duration(elapsedDurations[3]) * time.Hour * 24
|
|
||||||
}
|
|
||||||
|
|
||||||
start := time.Now().Add(-elapsed)
|
|
||||||
return start.Unix() * 1000, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
|
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
|
||||||
out, err := common.CallLsofWithContext(ctx, invoke, p.Pid, "-FR")
|
ppid, err := p.PpidWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, line := range out {
|
|
||||||
if len(line) >= 1 && line[0] == 'R' {
|
return NewProcessWithContext(ctx, ppid)
|
||||||
v, err := strconv.Atoi(line[1:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return NewProcessWithContext(ctx, int32(v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("could not find parent line")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) {
|
func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) {
|
||||||
@ -188,7 +149,7 @@ func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// See: http://unix.superglobalmegacorp.com/Net2/newsrc/sys/ucred.h.html
|
// See: http://unix.superglobalmegacorp.com/Net2/newsrc/sys/ucred.h.html
|
||||||
userEffectiveUID := int32(k.Eproc.Ucred.UID)
|
userEffectiveUID := int32(k.Eproc.Ucred.Uid)
|
||||||
|
|
||||||
return []int32{userEffectiveUID}, nil
|
return []int32{userEffectiveUID}, nil
|
||||||
}
|
}
|
||||||
@ -200,7 +161,7 @@ func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gids := make([]int32, 0, 3)
|
gids := make([]int32, 0, 3)
|
||||||
gids = append(gids, int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Ucred.Ngroups), int32(k.Eproc.Pcred.P_svgid))
|
gids = append(gids, int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Pcred.P_svgid))
|
||||||
|
|
||||||
return gids, nil
|
return gids, nil
|
||||||
}
|
}
|
||||||
@ -399,17 +360,8 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
|||||||
|
|
||||||
// Returns a proc as defined here:
|
// Returns a proc as defined here:
|
||||||
// http://unix.superglobalmegacorp.com/Net2/newsrc/sys/kinfo_proc.h.html
|
// http://unix.superglobalmegacorp.com/Net2/newsrc/sys/kinfo_proc.h.html
|
||||||
func (p *Process) getKProc() (*KinfoProc, error) {
|
func (p *Process) getKProc() (*unix.KinfoProc, error) {
|
||||||
buf, err := unix.SysctlRaw("kern.proc.pid", int(p.Pid))
|
return unix.SysctlKinfoProc("kern.proc.pid", int(p.Pid))
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
k, err := parseKinfoProc(buf)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &k, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// call ps command.
|
// call ps command.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user