From dd1330083397b9e01f4fbca02097a17c4ce05328 Mon Sep 17 00:00:00 2001 From: Shirou WAKAYAMA Date: Tue, 24 Nov 2015 00:04:20 +0900 Subject: [PATCH] process[linux,freebsd,darwin]: implements Children using pgrep. --- README.rst | 2 +- internal/common/common_unix.go | 26 ++++++++++++++++++++++++++ process/process_darwin.go | 16 ++++++++++++++-- process/process_freebsd.go | 16 ++++++++++++++-- process/process_linux.go | 14 +++++++++++++- process/process_test.go | 16 ++++++++++++++++ 6 files changed, 84 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index f4e8328ce..20fae2a6e 100644 --- a/README.rst +++ b/README.rst @@ -195,7 +195,7 @@ cpu_percent x x cpu_affinity memory_percent parent x x -children +children x x x connections x x is_running ================ ===== ======= ====== ======= diff --git a/internal/common/common_unix.go b/internal/common/common_unix.go index d0557ad25..6622eecc2 100644 --- a/internal/common/common_unix.go +++ b/internal/common/common_unix.go @@ -38,3 +38,29 @@ func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) { } return ret, nil } + +func CallPgrep(invoke Invoker, pid int32) ([]int32, error) { + var cmd []string + cmd = []string{"-P", strconv.Itoa(int(pid))} + pgrep, err := exec.LookPath("pgrep") + if err != nil { + return []int32{}, err + } + out, err := invoke.Command(pgrep, cmd...) + 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.Atoi(l) + if err != nil { + continue + } + ret = append(ret, int32(i)) + } + return ret, nil +} diff --git a/process/process_darwin.go b/process/process_darwin.go index 86b270b16..a8fce7d2e 100644 --- a/process/process_darwin.go +++ b/process/process_darwin.go @@ -10,8 +10,8 @@ import ( "syscall" "unsafe" - "github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/cpu" + "github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/net" ) @@ -278,7 +278,19 @@ func (p *Process) MemoryPercent() (float32, error) { } func (p *Process) Children() ([]*Process, error) { - return nil, common.NotImplementedError + pids, err := common.CallPgrep(invoke, p.Pid) + if err != nil { + return nil, err + } + ret := make([]*Process, 0, len(pids)) + for _, pid := range pids { + np, err := NewProcess(pid) + if err != nil { + return nil, err + } + ret = append(ret, np) + } + return ret, nil } func (p *Process) OpenFiles() ([]OpenFilesStat, error) { diff --git a/process/process_freebsd.go b/process/process_freebsd.go index d92543ce6..a5f0435bb 100644 --- a/process/process_freebsd.go +++ b/process/process_freebsd.go @@ -7,8 +7,8 @@ import ( "encoding/binary" "unsafe" - "github.com/shirou/gopsutil/internal/common" cpu "github.com/shirou/gopsutil/cpu" + "github.com/shirou/gopsutil/internal/common" net "github.com/shirou/gopsutil/net" ) @@ -168,7 +168,19 @@ func (p *Process) MemoryPercent() (float32, error) { } func (p *Process) Children() ([]*Process, error) { - return nil, common.NotImplementedError + pids, err := common.CallPgrep(invoke, p.Pid) + if err != nil { + return nil, err + } + ret := make([]*Process, 0, len(pids)) + for _, pid := range pids { + np, err := NewProcess(pid) + if err != nil { + return nil, err + } + ret = append(ret, np) + } + return ret, nil } func (p *Process) OpenFiles() ([]OpenFilesStat, error) { diff --git a/process/process_linux.go b/process/process_linux.go index 9855b74a6..affab54f0 100644 --- a/process/process_linux.go +++ b/process/process_linux.go @@ -203,7 +203,19 @@ func (p *Process) MemoryPercent() (float32, error) { } func (p *Process) Children() ([]*Process, error) { - return nil, common.NotImplementedError + pids, err := common.CallPgrep(invoke, p.Pid) + if err != nil { + return nil, err + } + ret := make([]*Process, 0, len(pids)) + for _, pid := range pids { + np, err := NewProcess(pid) + if err != nil { + return nil, err + } + ret = append(ret, np) + } + return ret, nil } func (p *Process) OpenFiles() ([]OpenFilesStat, error) { diff --git a/process/process_test.go b/process/process_test.go index 4cb475a19..153302e7f 100644 --- a/process/process_test.go +++ b/process/process_test.go @@ -312,3 +312,19 @@ func Test_Connections(t *testing.T) { t.Fatalf("wrong connections") } } + +func Test_Children(t *testing.T) { + p, err := NewProcess(1) + if err != nil { + t.Fatalf("new process error %v", err) + } + + c, err := p.Children() + if err != nil { + t.Fatalf("error %v", err) + } + if len(c) == 0 { + t.Fatalf("children is empty") + } + +}