From 1b8d61144d0ee66cd4cf886a7033f6b1859402ee Mon Sep 17 00:00:00 2001 From: Nikolay Sivko Date: Sun, 31 Aug 2014 14:46:23 +0400 Subject: [PATCH] fix Process.fillFromStatus --- process.go | 6 ++++ process_linux.go | 86 +++++++++++++++++++------------------------------------- 2 files changed, 35 insertions(+), 57 deletions(-) diff --git a/process.go b/process.go index 5d64721..47abc17 100644 --- a/process.go +++ b/process.go @@ -6,6 +6,12 @@ import ( type Process struct { Pid int32 `json:"pid"` + name string + status string + numCtxSwitches *NumCtxSwitchesStat + uids []int32 + gids []int32 + numThreads int32 } type OpenFilesStat struct { diff --git a/process_linux.go b/process_linux.go index dc77edf..f34f68b 100644 --- a/process_linux.go +++ b/process_linux.go @@ -57,7 +57,8 @@ func NewProcess(pid int32) (*Process, error) { p := &Process{ Pid: int32(pid), } - return p, nil + err := p.fillFromStatus() + return p, err } func (p *Process) Ppid() (int32, error) { @@ -68,11 +69,7 @@ func (p *Process) Ppid() (int32, error) { return ppid, nil } func (p *Process) Name() (string, error) { - name, _, _, _, _, _, err := p.fillFromStatus() - if err != nil { - return "", err - } - return name, nil + return p.name, nil } func (p *Process) Exe() (string, error) { return p.fillFromExe() @@ -95,25 +92,13 @@ func (p *Process) Parent() (*Process, error) { return nil, NotImplementedError } func (p *Process) Status() (string, error) { - _, status, _, _, _, _, err := p.fillFromStatus() - if err != nil { - return "", err - } - return status, nil + return p.status, nil } func (p *Process) Uids() ([]int32, error) { - _, _, uids, _, _, _, err := p.fillFromStatus() - if err != nil { - return nil, err - } - return uids, nil + return p.uids, nil } func (p *Process) Gids() ([]int32, error) { - _, _, _, gids, _, _, err := p.fillFromStatus() - if err != nil { - return nil, err - } - return gids, nil + return p.gids, nil } func (p *Process) Terminal() (string, error) { terminal, _, _, _, _, err := p.fillFromStat() @@ -139,21 +124,13 @@ func (p *Process) IOCounters() (*IOCountersStat, error) { return p.fillFromIO() } func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) { - _, _, _, _, _, numCtxSwitches, err := p.fillFromStatus() - if err != nil { - return nil, err - } - return numCtxSwitches, nil + return p.numCtxSwitches, nil } func (p *Process) NumFDs() (int32, error) { return 0, NotImplementedError } func (p *Process) NumThreads() (int32, error) { - _, _, _, _, numThreads, _, err := p.fillFromStatus() - if err != nil { - return 0, err - } - return numThreads, nil + return p.numThreads, nil } func (p *Process) Threads() (map[string]string, error) { ret := make(map[string]string, 0) @@ -405,59 +382,54 @@ func (p *Process) fillFromStatm() (*MemoryInfoStat, *MemoryInfoExStat, error) { } // Get various status from /proc/(pid)/status -func (p *Process) fillFromStatus() (string, string, []int32, []int32, int32, *NumCtxSwitchesStat, error) { +func (p *Process) fillFromStatus() error { pid := p.Pid statPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "status") contents, err := ioutil.ReadFile(statPath) if err != nil { - return "", "", nil, nil, 0, nil, err + return err } lines := strings.Split(string(contents), "\n") - name := "" - status := "" - var numThreads int32 var vol int32 var unvol int32 - var uids []int32 - var gids []int32 for _, line := range lines { - field := strings.Split(line, ":") - if len(field) < 2 { + tabParts := strings.SplitN(line, "\t", 1) + if len(tabParts) < 2 { continue } - // fmt.Printf("%s ->__%s__\n", field[0], strings.Trim(field[1], " \t")) - switch field[0] { + value := tabParts[1] + switch strings.TrimRight(tabParts[0], ":") { case "Name": - name = strings.Trim(field[1], " \t") + p.name = strings.Trim(value, " \t") case "State": // get between "(" and ")" - s := strings.Index(field[1], "(") + 1 - e := strings.Index(field[1], "(") + 1 - status = field[1][s:e] - // case "PPid": // filled by fillFromStat + s := strings.Index(value, "(") + 1 + e := strings.Index(value, "(") + 1 + p.status = value[s:e] case "Uid": - for _, i := range strings.Split(field[1], "\t") { - uids = append(uids, mustParseInt32(i)) + p.uids = make([]int32, 0, 4) + for _, i := range strings.Split(value, "\t") { + p.uids = append(p.uids, mustParseInt32(i)) } case "Gid": - for _, i := range strings.Split(field[1], "\t") { - gids = append(gids, mustParseInt32(i)) + p.gids = make([]int32, 0, 4) + for _, i := range strings.Split(value, "\t") { + p.gids = append(p.gids, mustParseInt32(i)) } case "Threads": - numThreads = mustParseInt32(field[1]) + p.numThreads = mustParseInt32(value) case "voluntary_ctxt_switches": - vol = mustParseInt32(field[1]) + vol = mustParseInt32(value) case "nonvoluntary_ctxt_switches": - unvol = mustParseInt32(field[1]) + unvol = mustParseInt32(value) } } - - numctx := &NumCtxSwitchesStat{ + p.numCtxSwitches = &NumCtxSwitchesStat{ Voluntary: vol, Involuntary: unvol, } - return name, status, uids, gids, numThreads, numctx, nil + return nil } func (p *Process) fillFromStat() (string, int32, *CPUTimesStat, int64, int32, error) {