1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00
2018-11-12 01:30:24 -08:00

304 lines
8.3 KiB
Go

package linux
import (
"io/ioutil"
"regexp"
"strconv"
"strings"
)
// Status information about the process.
type ProcessStat struct {
Pid uint64 `json:"pid"`
Comm string `json:"comm"`
State string `json:"state"`
Ppid int64 `json:"ppid"`
Pgrp int64 `json:"pgrp"`
Session int64 `json:"session"`
TtyNr int64 `json:"tty_nr"`
Tpgid int64 `json:"tpgid"`
Flags uint64 `json:"flags"`
Minflt uint64 `json:"minflt"`
Cminflt uint64 `json:"cminflt"`
Majflt uint64 `json:"majflt"`
Cmajflt uint64 `json:"cmajflt"`
Utime uint64 `json:"utime"`
Stime uint64 `json:"stime"`
Cutime int64 `json:"cutime"`
Cstime int64 `json:"cstime"`
Priority int64 `json:"priority"`
Nice int64 `json:"nice"`
NumThreads int64 `json:"num_threads"`
Itrealvalue int64 `json:"itrealvalue"`
Starttime uint64 `json:"starttime"`
Vsize uint64 `json:"vsize"`
Rss int64 `json:"rss"`
Rsslim uint64 `json:"rsslim"`
Startcode uint64 `json:"startcode"`
Endcode uint64 `json:"endcode"`
Startstack uint64 `json:"startstack"`
Kstkesp uint64 `json:"kstkesp"`
Kstkeip uint64 `json:"kstkeip"`
Signal uint64 `json:"signal"`
Blocked uint64 `json:"blocked"`
Sigignore uint64 `json:"sigignore"`
Sigcatch uint64 `json:"sigcatch"`
Wchan uint64 `json:"wchan"`
Nswap uint64 `json:"nswap"`
Cnswap uint64 `json:"cnswap"`
ExitSignal int64 `json:"exit_signal"`
Processor int64 `json:"processor"`
RtPriority uint64 `json:"rt_priority"`
Policy uint64 `json:"policy"`
DelayacctBlkioTicks uint64 `json:"delayacct_blkio_ticks"`
GuestTime uint64 `json:"guest_time"`
CguestTime int64 `json:"cguest_time"`
StartData uint64 `json:"start_data"`
EndData uint64 `json:"end_data"`
StartBrk uint64 `json:"start_brk"`
ArgStart uint64 `json:"arg_start"`
ArgEnd uint64 `json:"arg_end"`
EnvStart uint64 `json:"env_start"`
EnvEnd uint64 `json:"env_end"`
ExitCode int64 `json:"exit_code"`
}
var processStatRegExp = regexp.MustCompile("^(\\d+)( \\(.*?\\) )(.*)$")
func ReadProcessStat(path string) (*ProcessStat, error) {
b, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
s := string(b)
f := make([]string, 0, 32)
e := processStatRegExp.FindStringSubmatch(strings.TrimSpace(s))
// Inject process Pid
f = append(f, e[1])
// Inject process Comm
f = append(f, strings.TrimSpace(e[2]))
// Inject all remaining process info
f = append(f, (strings.Fields(e[3]))...)
stat := ProcessStat{}
for i := 0; i < len(f); i++ {
switch i {
case 0:
if stat.Pid, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 1:
stat.Comm = f[i]
case 2:
stat.State = f[i]
case 3:
if stat.Ppid, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 4:
if stat.Pgrp, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 5:
if stat.Session, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 6:
if stat.TtyNr, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 7:
if stat.Tpgid, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 8:
if stat.Flags, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 9:
if stat.Minflt, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 10:
if stat.Cminflt, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 11:
if stat.Majflt, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 12:
if stat.Cmajflt, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 13:
if stat.Utime, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 14:
if stat.Stime, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 15:
if stat.Cutime, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 16:
if stat.Cstime, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 17:
if stat.Priority, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 18:
if stat.Nice, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 19:
if stat.NumThreads, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 20:
if stat.Itrealvalue, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 21:
if stat.Starttime, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 22:
if stat.Vsize, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 23:
if stat.Rss, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 24:
if stat.Rsslim, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 25:
if stat.Startcode, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 26:
if stat.Endcode, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 27:
if stat.Startstack, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 28:
if stat.Kstkesp, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 29:
if stat.Kstkeip, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 30:
if stat.Signal, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 31:
if stat.Blocked, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 32:
if stat.Sigignore, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 33:
if stat.Sigcatch, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 34:
if stat.Wchan, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 35:
if stat.Nswap, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 36:
if stat.Cnswap, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 37:
if stat.ExitSignal, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 38:
if stat.Processor, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 39:
if stat.RtPriority, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 40:
if stat.Policy, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 41:
if stat.DelayacctBlkioTicks, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 42:
if stat.GuestTime, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 43:
if stat.CguestTime, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
case 44:
if stat.StartData, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 45:
if stat.EndData, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 46:
if stat.StartBrk, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 47:
if stat.ArgStart, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 48:
if stat.ArgEnd, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 49:
if stat.EnvStart, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 50:
if stat.EnvEnd, err = strconv.ParseUint(f[i], 10, 64); err != nil {
return nil, err
}
case 51:
if stat.ExitCode, err = strconv.ParseInt(f[i], 10, 64); err != nil {
return nil, err
}
}
}
return &stat, nil
}