process[darwin,linux]: implements Parent using lsof.

pull/77/head
Shirou WAKAYAMA 10 years ago
parent eb7739a6a5
commit d6ac361a24

@ -4,6 +4,7 @@ package process
import ( import (
"bytes" "bytes"
"fmt"
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall"
@ -92,7 +93,18 @@ func (p *Process) Cwd() (string, error) {
return "", common.NotImplementedError return "", common.NotImplementedError
} }
func (p *Process) Parent() (*Process, error) { func (p *Process) Parent() (*Process, error) {
return p, common.NotImplementedError r, err := callLsof("R", p.Pid)
if err != nil {
return nil, err
}
if len(r) != 1 { // TODO: pid 1
return nil, fmt.Errorf("wrong number of parents")
}
v, err := strconv.Atoi(r[0])
if err != nil {
return nil, err
}
return NewProcess(int32(v))
} }
func (p *Process) Status() (string, error) { func (p *Process) Status() (string, error) {
r, err := callPs("state", p.Pid, false) r, err := callPs("state", p.Pid, false)
@ -166,15 +178,6 @@ func (p *Process) NumFDs() (int32, error) {
return 0, common.NotImplementedError return 0, common.NotImplementedError
} }
func (p *Process) NumThreads() (int32, error) { func (p *Process) NumThreads() (int32, error) {
/*
k, err := p.getKProc()
if err != nil {
return 0, err
}
return k.KiNumthreads, nil
*/
r, err := callPs("utime,stime", p.Pid, true) r, err := callPs("utime,stime", p.Pid, true)
if err != nil { if err != nil {
return 0, err return 0, err
@ -412,3 +415,26 @@ func callPs(arg string, pid int32, threadOption bool) ([][]string, error) {
return ret, nil return ret, nil
} }
func callLsof(arg string, pid int32) ([]string, error) {
var cmd []string
if pid == 0 { // will get from all processes.
cmd = []string{"-F" + arg}
} else {
cmd = []string{"-a", "-F" + arg, "-p", strconv.Itoa(int(pid))}
}
out, err := invoke.Command("/usr/sbin/lsof", cmd...)
if err != nil {
return []string{}, err
}
lines := strings.Split(string(out), "\n")
var ret []string
for _, l := range lines[1:] {
if strings.HasPrefix(l, arg) {
ret = append(ret, l[1:]) // delete first char
}
}
return ret, nil
}

@ -4,6 +4,7 @@ package process
import ( import (
"encoding/json" "encoding/json"
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -11,10 +12,10 @@ import (
"strings" "strings"
"syscall" "syscall"
common "github.com/shirou/gopsutil/common" "github.com/shirou/gopsutil/common"
cpu "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/cpu"
host "github.com/shirou/gopsutil/host" "github.com/shirou/gopsutil/host"
net "github.com/shirou/gopsutil/net" "github.com/shirou/gopsutil/net"
) )
const ( const (
@ -94,7 +95,18 @@ func (p *Process) Cwd() (string, error) {
return p.fillFromCwd() return p.fillFromCwd()
} }
func (p *Process) Parent() (*Process, error) { func (p *Process) Parent() (*Process, error) {
return nil, common.NotImplementedError r, err := callLsof("R", p.Pid)
if err != nil {
return nil, err
}
if len(r) != 1 { // TODO: pid 1
return nil, fmt.Errorf("wrong number of parents")
}
v, err := strconv.Atoi(r[0])
if err != nil {
return nil, err
}
return NewProcess(int32(v))
} }
func (p *Process) Status() (string, error) { func (p *Process) Status() (string, error) {
err := p.fillFromStatus() err := p.fillFromStatus()
@ -619,3 +631,26 @@ func Pids() ([]int32, error) {
return ret, nil return ret, nil
} }
func callLsof(arg string, pid int32) ([]string, error) {
var cmd []string
if pid == 0 { // will get from all processes.
cmd = []string{"-F" + arg}
} else {
cmd = []string{"-a", "-F" + arg, "-p", strconv.Itoa(int(pid))}
}
out, err := invoke.Command("/usr/bin/lsof", cmd...)
if err != nil {
return []string{}, err
}
lines := strings.Split(string(out), "\n")
var ret []string
for _, l := range lines[1:] {
if strings.HasPrefix(l, arg) {
ret = append(ret, l[1:]) // delete first char
}
}
return ret, nil
}

@ -1,7 +1,6 @@
package process package process
import ( import (
"fmt"
"os" "os"
"runtime" "runtime"
"strings" "strings"
@ -38,7 +37,7 @@ func Test_Pids_Fail(t *testing.T) {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
invoke = common.FakeInvoke{Suffix: "fail", Error: fmt.Errorf("hoge")} invoke = common.FakeInvoke{Suffix: "fail"}
ret, err := Pids() ret, err := Pids()
invoke = common.Invoke{} invoke = common.Invoke{}
if err != nil { if err != nil {
@ -48,7 +47,6 @@ func Test_Pids_Fail(t *testing.T) {
t.Errorf("wrong getted pid nums: %v/%d", ret, len(ret)) t.Errorf("wrong getted pid nums: %v/%d", ret, len(ret))
} }
} }
func Test_Pid_exists(t *testing.T) { func Test_Pid_exists(t *testing.T) {
checkPid := os.Getpid() checkPid := os.Getpid()
@ -276,3 +274,18 @@ func Test_Process_CreateTime(t *testing.T) {
t.Errorf("process created time is wrong.") t.Errorf("process created time is wrong.")
} }
} }
func Test_Parent(t *testing.T) {
p := testGetProcess()
c, err := p.Parent()
if err != nil {
t.Errorf("error %v", err)
}
if c == nil {
t.Errorf("could not get parent")
}
if c.Pid == 0 {
t.Errorf("wrong parent pid")
}
}

Loading…
Cancel
Save