process: add meminfo, cmdline on darwin.

pull/43/merge
若山史郎 10 years ago
parent 20c3ddbfe5
commit 9d38e5c995

@ -150,24 +150,24 @@ Process class
================ ===== ======= ====== ======= ================ ===== ======= ====== =======
name Linux FreeBSD MacOSX Windows name Linux FreeBSD MacOSX Windows
pid x x b x pid x x x x
ppid x x b x ppid x x x x
name x x b name x x x
cmdline x cmdline x x
create_time x create_time x
status x x b status x x x
cwd x cwd x
exe x x x exe x x x
uids x x b uids x x x
gids x x b gids x x x
terminal x x b terminal x x x
io_counters x io_counters x
nice x nice x x
num_fds x num_fds x
num_ctx_switches x num_ctx_switches x
num_threads x x b num_threads x x x
cpu_times x cpu_times x
memory_info x x b memory_info x x x
memory_info_ex x memory_info_ex x
memory_maps x memory_maps x
open_files x open_files x
@ -176,7 +176,7 @@ suspend x x x
resume x x x resume x x x
terminate x x x terminate x x x
kill x x x kill x x x
username x x b username x
ionice ionice
rlimit rlimit
num_handlres num_handlres

@ -4,6 +4,9 @@ package process
import ( import (
"bytes" "bytes"
"os/exec"
"strconv"
"strings"
"syscall" "syscall"
"unsafe" "unsafe"
@ -48,12 +51,13 @@ func Pids() ([]int32, error) {
} }
func (p *Process) Ppid() (int32, error) { func (p *Process) Ppid() (int32, error) {
k, err := p.getKProc() r, err := callPs("ppid", p.Pid)
v, err := strconv.Atoi(r[0])
if err != nil { if err != nil {
return 0, err return 0, err
} }
return k.Proc.P_pid, nil return int32(v), err
} }
func (p *Process) Name() (string, error) { func (p *Process) Name() (string, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -67,7 +71,8 @@ func (p *Process) Exe() (string, error) {
return "", common.NotImplementedError return "", common.NotImplementedError
} }
func (p *Process) Cmdline() (string, error) { func (p *Process) Cmdline() (string, error) {
return p.Name() r, err := callPs("command", p.Pid)
return r[0], err
} }
func (p *Process) CreateTime() (int64, error) { func (p *Process) CreateTime() (int64, error) {
return 0, common.NotImplementedError return 0, common.NotImplementedError
@ -79,12 +84,8 @@ func (p *Process) Parent() (*Process, error) {
return p, common.NotImplementedError return p, common.NotImplementedError
} }
func (p *Process) Status() (string, error) { func (p *Process) Status() (string, error) {
k, err := p.getKProc() r, err := callPs("state", p.Pid)
if err != nil { return r[0], err
return "", err
}
return string(k.Proc.P_stat), nil // TODO
} }
func (p *Process) Uids() ([]int32, error) { func (p *Process) Uids() ([]int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -110,19 +111,21 @@ func (p *Process) Gids() ([]int32, error) {
return gids, nil return gids, nil
} }
func (p *Process) Terminal() (string, error) { func (p *Process) Terminal() (string, error) {
return "", common.NotImplementedError
/*
k, err := p.getKProc() k, err := p.getKProc()
if err != nil { if err != nil {
return "", err return "", err
} }
ttyNr := uint64(k.Eproc.Tdev) ttyNr := uint64(k.Eproc.Tdev)
termmap, err := getTerminalMap() termmap, err := getTerminalMap()
if err != nil { if err != nil {
return "", err return "", err
} }
return termmap[ttyNr], nil return termmap[ttyNr], nil
*/
} }
func (p *Process) Nice() (int32, error) { func (p *Process) Nice() (int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -170,14 +173,27 @@ func (p *Process) CPUAffinity() ([]int32, error) {
return nil, common.NotImplementedError return nil, common.NotImplementedError
} }
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) { func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
k, err := p.getKProc() r, err := callPs("rss,vsize,pagein", p.Pid)
if err != nil {
return nil, err
}
rss, err := strconv.Atoi(r[0])
if err != nil {
return nil, err
}
vms, err := strconv.Atoi(r[1])
if err != nil {
return nil, err
}
pagein, err := strconv.Atoi(r[2])
if err != nil { if err != nil {
return nil, err return nil, err
} }
ret := &MemoryInfoStat{ ret := &MemoryInfoStat{
RSS: uint64(k.Eproc.Xrssize), RSS: uint64(rss),
VMS: uint64(k.Eproc.Xsize), VMS: uint64(vms),
Swap: uint64(pagein),
} }
return ret, nil return ret, nil
@ -295,3 +311,23 @@ func NewProcess(pid int32) (*Process, error) {
return p, nil return p, nil
} }
// call ps command.
// Return value deletes Header line(you must not input wrong arg).
// And splited by Space. Caller have responsibility to manage.
func callPs(arg string, pid int32) ([]string, error) {
out, err := exec.Command("/bin/ps", "-o", arg, "-p", strconv.Itoa(int(pid))).Output()
if err != nil {
return []string{}, err
}
lines := strings.Split(string(out), "\n")
var ret []string
for _, r := range strings.Split(lines[1], " ") {
if r == "" {
continue
}
ret = append(ret, strings.TrimSpace(r))
}
return ret, nil
}

@ -3,6 +3,7 @@ package process
import ( import (
"os" "os"
"runtime" "runtime"
"strings"
"testing" "testing"
"time" "time"
) )
@ -74,7 +75,31 @@ func Test_Process_memory_maps(t *testing.T) {
t.Errorf("memory map get error %v", m) t.Errorf("memory map get error %v", m)
} }
} }
}
func Test_Process_MemoryInfo(t *testing.T) {
p := testGetProcess()
v, err := p.MemoryInfo()
if err != nil {
t.Errorf("geting ppid error %v", err)
}
empty := MemoryInfoStat{}
if *v == empty {
t.Errorf("could not get memory info %v", v)
}
}
func Test_Process_CmdLine(t *testing.T) {
p := testGetProcess()
v, err := p.Cmdline()
if err != nil {
t.Errorf("geting ppid error %v", err)
}
if !strings.HasSuffix(v, "/_test/process.test") {
t.Errorf("invalid cmd line %v", v)
}
} }
func Test_Process_Ppid(t *testing.T) { func Test_Process_Ppid(t *testing.T) {
@ -89,12 +114,36 @@ func Test_Process_Ppid(t *testing.T) {
} }
} }
func Test_Process_Status(t *testing.T) {
p := testGetProcess()
v, err := p.Status()
if err != nil {
t.Errorf("geting ppid error %v", err)
}
if v != "S+" {
t.Errorf("could not get state %v", v)
}
}
func Test_Process_Terminal(t *testing.T) {
p := testGetProcess()
v, err := p.Terminal()
if err != nil {
t.Errorf("geting terminal error %v", err)
}
if v != "S+" {
t.Errorf("could not get state %v", v)
}
}
func Test_Process_IOCounters(t *testing.T) { func Test_Process_IOCounters(t *testing.T) {
p := testGetProcess() p := testGetProcess()
v, err := p.IOCounters() v, err := p.IOCounters()
if err != nil { if err != nil {
t.Errorf("geting ppid error %v", err) t.Errorf("geting iocounter error %v", err)
return return
} }
empty := &IOCountersStat{} empty := &IOCountersStat{}

Loading…
Cancel
Save