From 75751224223dcdbadd184b8bd1dfffd5f1cee73b Mon Sep 17 00:00:00 2001 From: cat2neat Date: Sun, 20 Nov 2016 01:03:12 +0000 Subject: [PATCH 1/4] Impl FilterProcesses for unix --- process.go | 7 ++++++- process_test.go | 32 ++++++++++++++++++++++++++++++++ process_unix.go | 6 +++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/process.go b/process.go index 2b5e8ed..f00ee09 100644 --- a/process.go +++ b/process.go @@ -28,7 +28,12 @@ type Process interface { // process table, in which case the process table returned might contain // ephemeral entities that happened to be running when this was called. func Processes() ([]Process, error) { - return processes() + return processes(nil) +} + +// FilterProcesses returns processes that satisfy the predicate f. +func FilterProcesses(f func(Process) bool) ([]Process, error) { + return processes(f) } // FindProcess looks up a single process by pid. diff --git a/process_test.go b/process_test.go index 1bcbc32..0c1186f 100644 --- a/process_test.go +++ b/process_test.go @@ -2,6 +2,7 @@ package ps import ( "os" + "os/exec" "testing" ) @@ -43,3 +44,34 @@ func TestProcesses(t *testing.T) { t.Fatal("should have Go") } } + +func TestFilterProcesses(t *testing.T) { + // should have go + cmd := exec.Command("go") + err := cmd.Start() + if err != nil { + t.Fatalf("err: %s", err) + } + // Return true only if p is the process started by cmd.Start() + f := func(p Process) bool { + pid := os.Getpid() + if p.PPid() == pid { + return true + } + return false + } + p, err := FilterProcesses(f) + _ = cmd.Wait() + if err != nil { + t.Fatalf("err: %s", err) + } + + if len(p) != 1 { + t.Fatal("should have one go processe") + } + + if p[0].Executable() != "go" && p[0].Executable() != "go.exe" { + t.Fatal("should have one go processe") + } + +} diff --git a/process_unix.go b/process_unix.go index 578215a..6bf9e2a 100644 --- a/process_unix.go +++ b/process_unix.go @@ -75,7 +75,7 @@ func findProcess(pid int) (Process, error) { return newUnixProcess(pid) } -func processes() ([]Process, error) { +func processes(f func(Process) bool) ([]Process, error) { d, err := os.Open("/proc") if err != nil { return nil, err @@ -116,6 +116,10 @@ func processes() ([]Process, error) { continue } + if f != nil && !f(p) { + continue + } + results = append(results, p) } } From 6f6ada81c7c9cd285752ca6c66f9c90a9d08cd8f Mon Sep 17 00:00:00 2001 From: cat2neat Date: Sun, 20 Nov 2016 03:05:34 +0000 Subject: [PATCH 2/4] Impl FilterProcesses for freebsd --- process_freebsd.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/process_freebsd.go b/process_freebsd.go index 0212b66..2a4560c 100644 --- a/process_freebsd.go +++ b/process_freebsd.go @@ -172,7 +172,7 @@ func findProcess(pid int) (Process, error) { return newUnixProcess(pid) } -func processes() ([]Process, error) { +func processes(f func(Process) bool) ([]Process, error) { results := make([]Process, 0, 50) mib := []int32{CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0} @@ -198,6 +198,9 @@ func processes() ([]Process, error) { continue } p.ppid, p.pgrp, p.sid, p.binary = copy_params(&k) + if f != nil && !f(p) { + continue + } results = append(results, p) } From 49f104aa2ffe8ddfef73605847450be1d06a21dd Mon Sep 17 00:00:00 2001 From: cat2neat Date: Sun, 20 Nov 2016 03:05:53 +0000 Subject: [PATCH 3/4] Impl FilterProcesses for windows --- process_windows.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/process_windows.go b/process_windows.go index f151974..f823dad 100644 --- a/process_windows.go +++ b/process_windows.go @@ -75,21 +75,26 @@ func newWindowsProcess(e *PROCESSENTRY32) *WindowsProcess { } func findProcess(pid int) (Process, error) { - ps, err := processes() + f := func(p Process) bool { + if p.Pid() == pid { + return true + } + return false + } + ps, err := FilterProcesses(f) + if err != nil { return nil, err } - for _, p := range ps { - if p.Pid() == pid { - return p, nil - } + if len(ps) == 0 { + return nil, nil } - return nil, nil + return ps[0], nil } -func processes() ([]Process, error) { +func processes(f func(Process) bool) ([]Process, error) { handle, _, _ := procCreateToolhelp32Snapshot.Call( 0x00000002, 0) @@ -107,7 +112,10 @@ func processes() ([]Process, error) { results := make([]Process, 0, 50) for { - results = append(results, newWindowsProcess(&entry)) + p := newWindowsProcess(&entry) + if f == nil || f(p) { + results = append(results, p) + } ret, _, _ := procProcess32Next.Call(handle, uintptr(unsafe.Pointer(&entry))) if ret == 0 { From fcea6f216da0a2f59f356f33a3dd59bebfba7cec Mon Sep 17 00:00:00 2001 From: cat2neat Date: Sun, 20 Nov 2016 03:06:06 +0000 Subject: [PATCH 4/4] Impl FilterProcesses for darwin --- process_darwin.go | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/process_darwin.go b/process_darwin.go index 5ee87fb..3a82533 100644 --- a/process_darwin.go +++ b/process_darwin.go @@ -28,49 +28,54 @@ func (p *DarwinProcess) Executable() string { } func findProcess(pid int) (Process, error) { - ps, err := processes() + f := func(p Process) bool { + if p.Pid() == pid { + return true + } + return false + } + ps, err := FilterProcesses(f) + if err != nil { return nil, err } - for _, p := range ps { - if p.Pid() == pid { - return p, nil - } + if len(ps) == 0 { + return nil, nil } - return nil, nil + return ps[0], nil } -func processes() ([]Process, error) { +func processes(f func(Process) bool) ([]Process, error) { buf, err := darwinSyscall() if err != nil { return nil, err } - procs := make([]*kinfoProc, 0, 50) + procs := make([]Process, 0, 50) + proc := &kinfoProc{} k := 0 for i := _KINFO_STRUCT_SIZE; i < buf.Len(); i += _KINFO_STRUCT_SIZE { - proc := &kinfoProc{} err = binary.Read(bytes.NewBuffer(buf.Bytes()[k:i]), binary.LittleEndian, proc) if err != nil { return nil, err } - k = i - procs = append(procs, proc) - } - darwinProcs := make([]Process, len(procs)) - for i, p := range procs { - darwinProcs[i] = &DarwinProcess{ - pid: int(p.Pid), - ppid: int(p.PPid), - binary: darwinCstring(p.Comm), + dp := &DarwinProcess{ + pid: int(proc.Pid), + ppid: int(proc.PPid), + binary: darwinCstring(proc.Comm), } + if f != nil && !f(dp) { + continue + } + + procs = append(procs, dp) } - return darwinProcs, nil + return procs, nil } func darwinCstring(s [16]byte) string {