godep update for procstat
This commit is contained in:
parent
fdf00c1be6
commit
5cc26bb640
|
@ -195,6 +195,11 @@
|
||||||
"Comment": "1.0.0-161-g3303647",
|
"Comment": "1.0.0-161-g3303647",
|
||||||
"Rev": "3303647209557312e5db51450ea8bbdef56d5176"
|
"Rev": "3303647209557312e5db51450ea8bbdef56d5176"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/shirou/gopsutil/host",
|
||||||
|
"Comment": "1.0.0-153-gc1313e7",
|
||||||
|
"Rev": "c1313e76341b18456212c5645d1daa7f132ac50e"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/shirou/gopsutil/load",
|
"ImportPath": "github.com/shirou/gopsutil/load",
|
||||||
"Comment": "1.0.0-161-g3303647",
|
"Comment": "1.0.0-161-g3303647",
|
||||||
|
@ -210,6 +215,11 @@
|
||||||
"Comment": "1.0.0-161-g3303647",
|
"Comment": "1.0.0-161-g3303647",
|
||||||
"Rev": "3303647209557312e5db51450ea8bbdef56d5176"
|
"Rev": "3303647209557312e5db51450ea8bbdef56d5176"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/shirou/gopsutil/process",
|
||||||
|
"Comment": "1.0.0-153-gc1313e7",
|
||||||
|
"Rev": "c1313e76341b18456212c5645d1daa7f132ac50e"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/streadway/amqp",
|
"ImportPath": "github.com/streadway/amqp",
|
||||||
"Rev": "f4879ba28fffbb576743b03622a9ff20461826b2"
|
"Rev": "f4879ba28fffbb576743b03622a9ff20461826b2"
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A HostInfoStat describes the host status.
|
||||||
|
// This is not in the psutil but it useful.
|
||||||
|
type HostInfoStat struct {
|
||||||
|
Hostname string `json:"hostname"`
|
||||||
|
Uptime uint64 `json:"uptime"`
|
||||||
|
Procs uint64 `json:"procs"` // number of processes
|
||||||
|
OS string `json:"os"` // ex: freebsd, linux
|
||||||
|
Platform string `json:"platform"` // ex: ubuntu, linuxmint
|
||||||
|
PlatformFamily string `json:"platform_family"` // ex: debian, rhel
|
||||||
|
PlatformVersion string `json:"platform_version"`
|
||||||
|
VirtualizationSystem string `json:"virtualization_system"`
|
||||||
|
VirtualizationRole string `json:"virtualization_role"` // guest or host
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserStat struct {
|
||||||
|
User string `json:"user"`
|
||||||
|
Terminal string `json:"terminal"`
|
||||||
|
Host string `json:"host"`
|
||||||
|
Started int `json:"started"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h HostInfoStat) String() string {
|
||||||
|
s, _ := json.Marshal(h)
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UserStat) String() string {
|
||||||
|
s, _ := json.Marshal(u)
|
||||||
|
return string(s)
|
||||||
|
}
|
139
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_darwin.go
generated
vendored
Normal file
139
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
// +build darwin
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
common "github.com/shirou/gopsutil/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
func HostInfo() (*HostInfoStat, error) {
|
||||||
|
ret := &HostInfoStat{
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
PlatformFamily: "darwin",
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
ret.Hostname = hostname
|
||||||
|
|
||||||
|
platform, family, version, err := GetPlatformInformation()
|
||||||
|
if err == nil {
|
||||||
|
ret.Platform = platform
|
||||||
|
ret.PlatformFamily = family
|
||||||
|
ret.PlatformVersion = version
|
||||||
|
}
|
||||||
|
system, role, err := GetVirtualization()
|
||||||
|
if err == nil {
|
||||||
|
ret.VirtualizationSystem = system
|
||||||
|
ret.VirtualizationRole = role
|
||||||
|
}
|
||||||
|
|
||||||
|
values, err := common.DoSysctrl("kern.boottime")
|
||||||
|
if err == nil {
|
||||||
|
// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
|
||||||
|
v := strings.Replace(values[2], ",", "", 1)
|
||||||
|
t, err := strconv.ParseUint(v, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
ret.Uptime = t
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func BootTime() (uint64, error) {
|
||||||
|
values, err := common.DoSysctrl("kern.boottime")
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
|
||||||
|
v := strings.Replace(values[2], ",", "", 1)
|
||||||
|
|
||||||
|
boottime, err := strconv.ParseInt(v, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return uint64(boottime), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Users() ([]UserStat, error) {
|
||||||
|
utmpfile := "/var/run/utmpx"
|
||||||
|
var ret []UserStat
|
||||||
|
|
||||||
|
file, err := os.Open(utmpfile)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u := Utmpx{}
|
||||||
|
entrySize := int(unsafe.Sizeof(u))
|
||||||
|
count := len(buf) / entrySize
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
b := buf[i*entrySize : i*entrySize+entrySize]
|
||||||
|
|
||||||
|
var u Utmpx
|
||||||
|
br := bytes.NewReader(b)
|
||||||
|
err := binary.Read(br, binary.LittleEndian, &u)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if u.Type != 7 { // skip if not USERPROCESS
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
user := UserStat{
|
||||||
|
User: common.IntToString(u.User[:]),
|
||||||
|
Terminal: common.IntToString(u.Line[:]),
|
||||||
|
Host: common.IntToString(u.Host[:]),
|
||||||
|
Started: int(u.Tv.Sec),
|
||||||
|
}
|
||||||
|
ret = append(ret, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPlatformInformation() (string, string, string, error) {
|
||||||
|
platform := ""
|
||||||
|
family := ""
|
||||||
|
version := ""
|
||||||
|
|
||||||
|
out, err := exec.Command("uname", "-s").Output()
|
||||||
|
if err == nil {
|
||||||
|
platform = strings.ToLower(strings.TrimSpace(string(out)))
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err = exec.Command("uname", "-r").Output()
|
||||||
|
if err == nil {
|
||||||
|
version = strings.ToLower(strings.TrimSpace(string(out)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return platform, family, version, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVirtualization() (string, string, error) {
|
||||||
|
system := ""
|
||||||
|
role := ""
|
||||||
|
|
||||||
|
return system, role, nil
|
||||||
|
}
|
19
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_darwin_amd64.go
generated
vendored
Normal file
19
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_darwin_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_darwin.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
type Utmpx struct {
|
||||||
|
User [256]int8
|
||||||
|
Id [4]int8
|
||||||
|
Line [32]int8
|
||||||
|
Pid int32
|
||||||
|
Type int16
|
||||||
|
Pad_cgo_0 [6]byte
|
||||||
|
Tv Timeval
|
||||||
|
Host [256]int8
|
||||||
|
Pad [16]uint32
|
||||||
|
}
|
||||||
|
type Timeval struct {
|
||||||
|
Sec int32
|
||||||
|
}
|
185
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_freebsd.go
generated
vendored
Normal file
185
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_freebsd.go
generated
vendored
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
// +build freebsd
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
common "github.com/shirou/gopsutil/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
UTNameSize = 16 /* see MAXLOGNAME in <sys/param.h> */
|
||||||
|
UTLineSize = 8
|
||||||
|
UTHostSize = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
func HostInfo() (*HostInfoStat, error) {
|
||||||
|
ret := &HostInfoStat{
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
PlatformFamily: "freebsd",
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
ret.Hostname = hostname
|
||||||
|
|
||||||
|
platform, family, version, err := GetPlatformInformation()
|
||||||
|
if err == nil {
|
||||||
|
ret.Platform = platform
|
||||||
|
ret.PlatformFamily = family
|
||||||
|
ret.PlatformVersion = version
|
||||||
|
}
|
||||||
|
system, role, err := GetVirtualization()
|
||||||
|
if err == nil {
|
||||||
|
ret.VirtualizationSystem = system
|
||||||
|
ret.VirtualizationRole = role
|
||||||
|
}
|
||||||
|
|
||||||
|
values, err := common.DoSysctrl("kern.boottime")
|
||||||
|
if err == nil {
|
||||||
|
// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
|
||||||
|
v := strings.Replace(values[2], ",", "", 1)
|
||||||
|
t, err := strconv.ParseUint(v, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
ret.Uptime = t
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func BootTime() (int64, error) {
|
||||||
|
values, err := common.DoSysctrl("kern.boottime")
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
|
||||||
|
v := strings.Replace(values[2], ",", "", 1)
|
||||||
|
|
||||||
|
boottime, err := strconv.ParseInt(v, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return boottime, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Users() ([]UserStat, error) {
|
||||||
|
utmpfile := "/var/run/utx.active"
|
||||||
|
if !common.PathExists(utmpfile) {
|
||||||
|
utmpfile = "/var/run/utmp" // before 9.0
|
||||||
|
return getUsersFromUtmp(utmpfile)
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret []UserStat
|
||||||
|
file, err := os.Open(utmpfile)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u := Utmpx{}
|
||||||
|
entrySize := int(unsafe.Sizeof(u)) - 3
|
||||||
|
entrySize = 197 // TODO: why should 197
|
||||||
|
count := len(buf) / entrySize
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
b := buf[i*entrySize : i*entrySize+entrySize]
|
||||||
|
var u Utmpx
|
||||||
|
br := bytes.NewReader(b)
|
||||||
|
err := binary.Read(br, binary.LittleEndian, &u)
|
||||||
|
if err != nil || u.Type != 4 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sec := (binary.LittleEndian.Uint32(u.Tv.Sec[:])) / 2 // TODO:
|
||||||
|
user := UserStat{
|
||||||
|
User: common.IntToString(u.User[:]),
|
||||||
|
Terminal: common.IntToString(u.Line[:]),
|
||||||
|
Host: common.IntToString(u.Host[:]),
|
||||||
|
Started: int(sec),
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = append(ret, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPlatformInformation() (string, string, string, error) {
|
||||||
|
platform := ""
|
||||||
|
family := ""
|
||||||
|
version := ""
|
||||||
|
|
||||||
|
out, err := exec.Command("uname", "-s").Output()
|
||||||
|
if err == nil {
|
||||||
|
platform = strings.ToLower(strings.TrimSpace(string(out)))
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err = exec.Command("uname", "-r").Output()
|
||||||
|
if err == nil {
|
||||||
|
version = strings.ToLower(strings.TrimSpace(string(out)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return platform, family, version, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVirtualization() (string, string, error) {
|
||||||
|
system := ""
|
||||||
|
role := ""
|
||||||
|
|
||||||
|
return system, role, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// before 9.0
|
||||||
|
func getUsersFromUtmp(utmpfile string) ([]UserStat, error) {
|
||||||
|
var ret []UserStat
|
||||||
|
file, err := os.Open(utmpfile)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
buf, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u := Utmp{}
|
||||||
|
entrySize := int(unsafe.Sizeof(u))
|
||||||
|
count := len(buf) / entrySize
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
b := buf[i*entrySize : i*entrySize+entrySize]
|
||||||
|
var u Utmp
|
||||||
|
br := bytes.NewReader(b)
|
||||||
|
err := binary.Read(br, binary.LittleEndian, &u)
|
||||||
|
if err != nil || u.Time == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
user := UserStat{
|
||||||
|
User: common.IntToString(u.Name[:]),
|
||||||
|
Terminal: common.IntToString(u.Line[:]),
|
||||||
|
Host: common.IntToString(u.Host[:]),
|
||||||
|
Started: int(u.Time),
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = append(ret, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
41
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_freebsd_amd64.go
generated
vendored
Normal file
41
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_freebsd_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_freebsd.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x8
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x8
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int64
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type Utmp struct {
|
||||||
|
Line [8]int8
|
||||||
|
Name [16]int8
|
||||||
|
Host [16]int8
|
||||||
|
Time int32
|
||||||
|
}
|
||||||
|
type Utmpx struct {
|
||||||
|
Type int16
|
||||||
|
Tv Timeval
|
||||||
|
Id [8]int8
|
||||||
|
Pid int32
|
||||||
|
User [32]int8
|
||||||
|
Line [16]int8
|
||||||
|
Host [125]int8
|
||||||
|
// Host [128]int8
|
||||||
|
// X__ut_spare [64]int8
|
||||||
|
}
|
||||||
|
type Timeval struct {
|
||||||
|
Sec [4]byte
|
||||||
|
Usec [3]byte
|
||||||
|
}
|
402
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux.go
generated
vendored
Normal file
402
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,402 @@
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
common "github.com/shirou/gopsutil/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LSB struct {
|
||||||
|
ID string
|
||||||
|
Release string
|
||||||
|
Codename string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
func HostInfo() (*HostInfoStat, error) {
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := &HostInfoStat{
|
||||||
|
Hostname: hostname,
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
}
|
||||||
|
|
||||||
|
platform, family, version, err := GetPlatformInformation()
|
||||||
|
if err == nil {
|
||||||
|
ret.Platform = platform
|
||||||
|
ret.PlatformFamily = family
|
||||||
|
ret.PlatformVersion = version
|
||||||
|
}
|
||||||
|
system, role, err := GetVirtualization()
|
||||||
|
if err == nil {
|
||||||
|
ret.VirtualizationSystem = system
|
||||||
|
ret.VirtualizationRole = role
|
||||||
|
}
|
||||||
|
uptime, err := BootTime()
|
||||||
|
if err == nil {
|
||||||
|
ret.Uptime = uptime
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BootTime returns the system boot time expressed in seconds since the epoch.
|
||||||
|
func BootTime() (uint64, error) {
|
||||||
|
lines, err := common.ReadLines("/proc/stat")
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.HasPrefix(line, "btime") {
|
||||||
|
f := strings.Fields(line)
|
||||||
|
if len(f) != 2 {
|
||||||
|
return 0, fmt.Errorf("wrong btime format")
|
||||||
|
}
|
||||||
|
b, err := strconv.ParseInt(f[1], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uint64(b), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, fmt.Errorf("could not find btime")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Users() ([]UserStat, error) {
|
||||||
|
utmpfile := "/var/run/utmp"
|
||||||
|
|
||||||
|
file, err := os.Open(utmpfile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u := utmp{}
|
||||||
|
entrySize := int(unsafe.Sizeof(u))
|
||||||
|
count := len(buf) / entrySize
|
||||||
|
|
||||||
|
ret := make([]UserStat, 0, count)
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
b := buf[i*entrySize : i*entrySize+entrySize]
|
||||||
|
|
||||||
|
var u utmp
|
||||||
|
br := bytes.NewReader(b)
|
||||||
|
err := binary.Read(br, binary.LittleEndian, &u)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
user := UserStat{
|
||||||
|
User: common.IntToString(u.User[:]),
|
||||||
|
Terminal: common.IntToString(u.Line[:]),
|
||||||
|
Host: common.IntToString(u.Host[:]),
|
||||||
|
Started: int(u.Tv.TvSec),
|
||||||
|
}
|
||||||
|
ret = append(ret, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLSB() (*LSB, error) {
|
||||||
|
ret := &LSB{}
|
||||||
|
if common.PathExists("/etc/lsb-release") {
|
||||||
|
contents, err := common.ReadLines("/etc/lsb-release")
|
||||||
|
if err != nil {
|
||||||
|
return ret, err // return empty
|
||||||
|
}
|
||||||
|
for _, line := range contents {
|
||||||
|
field := strings.Split(line, "=")
|
||||||
|
if len(field) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch field[0] {
|
||||||
|
case "DISTRIB_ID":
|
||||||
|
ret.ID = field[1]
|
||||||
|
case "DISTRIB_RELEASE":
|
||||||
|
ret.Release = field[1]
|
||||||
|
case "DISTRIB_CODENAME":
|
||||||
|
ret.Codename = field[1]
|
||||||
|
case "DISTRIB_DESCRIPTION":
|
||||||
|
ret.Description = field[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if common.PathExists("/usr/bin/lsb_release") {
|
||||||
|
out, err := exec.Command("/usr/bin/lsb_release").Output()
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
for _, line := range strings.Split(string(out), "\n") {
|
||||||
|
field := strings.Split(line, ":")
|
||||||
|
if len(field) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch field[0] {
|
||||||
|
case "Distributor ID":
|
||||||
|
ret.ID = field[1]
|
||||||
|
case "Release":
|
||||||
|
ret.Release = field[1]
|
||||||
|
case "Codename":
|
||||||
|
ret.Codename = field[1]
|
||||||
|
case "Description":
|
||||||
|
ret.Description = field[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPlatformInformation() (platform string, family string, version string, err error) {
|
||||||
|
|
||||||
|
lsb, err := getLSB()
|
||||||
|
if err != nil {
|
||||||
|
lsb = &LSB{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if common.PathExists("/etc/oracle-release") {
|
||||||
|
platform = "oracle"
|
||||||
|
contents, err := common.ReadLines("/etc/oracle-release")
|
||||||
|
if err == nil {
|
||||||
|
version = getRedhatishVersion(contents)
|
||||||
|
}
|
||||||
|
} else if common.PathExists("/etc/enterprise-release") {
|
||||||
|
platform = "oracle"
|
||||||
|
contents, err := common.ReadLines("/etc/enterprise-release")
|
||||||
|
if err == nil {
|
||||||
|
version = getRedhatishVersion(contents)
|
||||||
|
}
|
||||||
|
} else if common.PathExists("/etc/debian_version") {
|
||||||
|
if lsb.ID == "Ubuntu" {
|
||||||
|
platform = "ubuntu"
|
||||||
|
version = lsb.Release
|
||||||
|
} else if lsb.ID == "LinuxMint" {
|
||||||
|
platform = "linuxmint"
|
||||||
|
version = lsb.Release
|
||||||
|
} else {
|
||||||
|
if common.PathExists("/usr/bin/raspi-config") {
|
||||||
|
platform = "raspbian"
|
||||||
|
} else {
|
||||||
|
platform = "debian"
|
||||||
|
}
|
||||||
|
contents, err := common.ReadLines("/etc/debian_version")
|
||||||
|
if err == nil {
|
||||||
|
version = contents[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if common.PathExists("/etc/redhat-release") {
|
||||||
|
contents, err := common.ReadLines("/etc/redhat-release")
|
||||||
|
if err == nil {
|
||||||
|
version = getRedhatishVersion(contents)
|
||||||
|
platform = getRedhatishPlatform(contents)
|
||||||
|
}
|
||||||
|
} else if common.PathExists("/etc/system-release") {
|
||||||
|
contents, err := common.ReadLines("/etc/system-release")
|
||||||
|
if err == nil {
|
||||||
|
version = getRedhatishVersion(contents)
|
||||||
|
platform = getRedhatishPlatform(contents)
|
||||||
|
}
|
||||||
|
} else if common.PathExists("/etc/gentoo-release") {
|
||||||
|
platform = "gentoo"
|
||||||
|
contents, err := common.ReadLines("/etc/gentoo-release")
|
||||||
|
if err == nil {
|
||||||
|
version = getRedhatishVersion(contents)
|
||||||
|
}
|
||||||
|
} else if common.PathExists("/etc/SuSE-release") {
|
||||||
|
contents, err := common.ReadLines("/etc/SuSE-release")
|
||||||
|
if err == nil {
|
||||||
|
version = getSuseVersion(contents)
|
||||||
|
platform = getSusePlatform(contents)
|
||||||
|
}
|
||||||
|
// TODO: slackware detecion
|
||||||
|
} else if common.PathExists("/etc/arch-release") {
|
||||||
|
platform = "arch"
|
||||||
|
// TODO: exherbo detection
|
||||||
|
} else if lsb.ID == "RedHat" {
|
||||||
|
platform = "redhat"
|
||||||
|
version = lsb.Release
|
||||||
|
} else if lsb.ID == "Amazon" {
|
||||||
|
platform = "amazon"
|
||||||
|
version = lsb.Release
|
||||||
|
} else if lsb.ID == "ScientificSL" {
|
||||||
|
platform = "scientific"
|
||||||
|
version = lsb.Release
|
||||||
|
} else if lsb.ID == "XenServer" {
|
||||||
|
platform = "xenserver"
|
||||||
|
version = lsb.Release
|
||||||
|
} else if lsb.ID != "" {
|
||||||
|
platform = strings.ToLower(lsb.ID)
|
||||||
|
version = lsb.Release
|
||||||
|
}
|
||||||
|
|
||||||
|
switch platform {
|
||||||
|
case "debian", "ubuntu", "linuxmint", "raspbian":
|
||||||
|
family = "debian"
|
||||||
|
case "fedora":
|
||||||
|
family = "fedora"
|
||||||
|
case "oracle", "centos", "redhat", "scientific", "enterpriseenterprise", "amazon", "xenserver", "cloudlinux", "ibm_powerkvm":
|
||||||
|
family = "rhel"
|
||||||
|
case "suse", "opensuse":
|
||||||
|
family = "suse"
|
||||||
|
case "gentoo":
|
||||||
|
family = "gentoo"
|
||||||
|
case "slackware":
|
||||||
|
family = "slackware"
|
||||||
|
case "arch":
|
||||||
|
family = "arch"
|
||||||
|
case "exherbo":
|
||||||
|
family = "exherbo"
|
||||||
|
}
|
||||||
|
|
||||||
|
return platform, family, version, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRedhatishVersion(contents []string) string {
|
||||||
|
c := strings.ToLower(strings.Join(contents, ""))
|
||||||
|
|
||||||
|
if strings.Contains(c, "rawhide") {
|
||||||
|
return "rawhide"
|
||||||
|
}
|
||||||
|
if matches := regexp.MustCompile(`release (\d[\d.]*)`).FindStringSubmatch(c); matches != nil {
|
||||||
|
return matches[1]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRedhatishPlatform(contents []string) string {
|
||||||
|
c := strings.ToLower(strings.Join(contents, ""))
|
||||||
|
|
||||||
|
if strings.Contains(c, "red hat") {
|
||||||
|
return "redhat"
|
||||||
|
}
|
||||||
|
f := strings.Split(c, " ")
|
||||||
|
|
||||||
|
return f[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSuseVersion(contents []string) string {
|
||||||
|
version := ""
|
||||||
|
for _, line := range contents {
|
||||||
|
if matches := regexp.MustCompile(`VERSION = ([\d.]+)`).FindStringSubmatch(line); matches != nil {
|
||||||
|
version = matches[1]
|
||||||
|
} else if matches := regexp.MustCompile(`PATCHLEVEL = ([\d]+)`).FindStringSubmatch(line); matches != nil {
|
||||||
|
version = version + "." + matches[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSusePlatform(contents []string) string {
|
||||||
|
c := strings.ToLower(strings.Join(contents, ""))
|
||||||
|
if strings.Contains(c, "opensuse") {
|
||||||
|
return "opensuse"
|
||||||
|
}
|
||||||
|
return "suse"
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVirtualization() (string, string, error) {
|
||||||
|
var system string
|
||||||
|
var role string
|
||||||
|
|
||||||
|
if common.PathExists("/proc/xen") {
|
||||||
|
system = "xen"
|
||||||
|
role = "guest" // assume guest
|
||||||
|
|
||||||
|
if common.PathExists("/proc/xen/capabilities") {
|
||||||
|
contents, err := common.ReadLines("/proc/xen/capabilities")
|
||||||
|
if err == nil {
|
||||||
|
if common.StringsHas(contents, "control_d") {
|
||||||
|
role = "host"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if common.PathExists("/proc/modules") {
|
||||||
|
contents, err := common.ReadLines("/proc/modules")
|
||||||
|
if err == nil {
|
||||||
|
if common.StringsContains(contents, "kvm") {
|
||||||
|
system = "kvm"
|
||||||
|
role = "host"
|
||||||
|
} else if common.StringsContains(contents, "vboxdrv") {
|
||||||
|
system = "vbox"
|
||||||
|
role = "host"
|
||||||
|
} else if common.StringsContains(contents, "vboxguest") {
|
||||||
|
system = "vbox"
|
||||||
|
role = "guest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if common.PathExists("/proc/cpuinfo") {
|
||||||
|
contents, err := common.ReadLines("/proc/cpuinfo")
|
||||||
|
if err == nil {
|
||||||
|
if common.StringsHas(contents, "QEMU Virtual CPU") ||
|
||||||
|
common.StringsHas(contents, "Common KVM processor") ||
|
||||||
|
common.StringsHas(contents, "Common 32-bit KVM processor") {
|
||||||
|
system = "kvm"
|
||||||
|
role = "guest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if common.PathExists("/proc/bc/0") {
|
||||||
|
system = "openvz"
|
||||||
|
role = "host"
|
||||||
|
} else if common.PathExists("/proc/vz") {
|
||||||
|
system = "openvz"
|
||||||
|
role = "guest"
|
||||||
|
}
|
||||||
|
|
||||||
|
// not use dmidecode because it requires root
|
||||||
|
|
||||||
|
if common.PathExists("/proc/self/status") {
|
||||||
|
contents, err := common.ReadLines("/proc/self/status")
|
||||||
|
if err == nil {
|
||||||
|
|
||||||
|
if common.StringsHas(contents, "s_context:") ||
|
||||||
|
common.StringsHas(contents, "VxID:") {
|
||||||
|
system = "linux-vserver"
|
||||||
|
}
|
||||||
|
// TODO: guest or host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if common.PathExists("/proc/self/cgroup") {
|
||||||
|
contents, err := common.ReadLines("/proc/self/cgroup")
|
||||||
|
if err == nil {
|
||||||
|
if common.StringsHas(contents, "lxc") ||
|
||||||
|
common.StringsHas(contents, "docker") {
|
||||||
|
system = "lxc"
|
||||||
|
role = "guest"
|
||||||
|
} else if common.PathExists("/usr/bin/lxc-version") { // TODO: which
|
||||||
|
system = "lxc"
|
||||||
|
role = "host"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return system, role, nil
|
||||||
|
}
|
44
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux_386.go
generated
vendored
Normal file
44
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux_386.go
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// ATTENTION - FILE MANUAL FIXED AFTER CGO.
|
||||||
|
// Fixed line: Tv _Ctype_struct_timeval -> Tv UtTv
|
||||||
|
// Created by cgo -godefs, MANUAL FIXED
|
||||||
|
// cgo -godefs types_linux.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x4
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x4
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int32
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type utmp struct {
|
||||||
|
Type int16
|
||||||
|
Pad_cgo_0 [2]byte
|
||||||
|
Pid int32
|
||||||
|
Line [32]int8
|
||||||
|
Id [4]int8
|
||||||
|
User [32]int8
|
||||||
|
Host [256]int8
|
||||||
|
Exit exit_status
|
||||||
|
Session int32
|
||||||
|
Tv UtTv
|
||||||
|
Addr_v6 [4]int32
|
||||||
|
X__unused [20]int8
|
||||||
|
}
|
||||||
|
type exit_status struct {
|
||||||
|
Termination int16
|
||||||
|
Exit int16
|
||||||
|
}
|
||||||
|
type UtTv struct {
|
||||||
|
TvSec int32
|
||||||
|
TvUsec int32
|
||||||
|
}
|
42
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux_amd64.go
generated
vendored
Normal file
42
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_linux.go
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x8
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x8
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int64
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type utmp struct {
|
||||||
|
Type int16
|
||||||
|
Pad_cgo_0 [2]byte
|
||||||
|
Pid int32
|
||||||
|
Line [32]int8
|
||||||
|
Id [4]int8
|
||||||
|
User [32]int8
|
||||||
|
Host [256]int8
|
||||||
|
Exit exit_status
|
||||||
|
Session int32
|
||||||
|
Tv UtTv
|
||||||
|
Addr_v6 [4]int32
|
||||||
|
X__glibc_reserved [20]int8
|
||||||
|
}
|
||||||
|
type exit_status struct {
|
||||||
|
Termination int16
|
||||||
|
Exit int16
|
||||||
|
}
|
||||||
|
type UtTv struct {
|
||||||
|
TvSec int32
|
||||||
|
TvUsec int32
|
||||||
|
}
|
27
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux_arm.go
generated
vendored
Normal file
27
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux_arm.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// +build linux
|
||||||
|
// +build arm
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
type exitStatus struct {
|
||||||
|
Etermination int16 // Process termination status.
|
||||||
|
Eexit int16 // Process exit status.
|
||||||
|
}
|
||||||
|
type timeval struct {
|
||||||
|
TvSec uint32 // Seconds.
|
||||||
|
TvUsec uint32 // Microseconds.
|
||||||
|
}
|
||||||
|
|
||||||
|
type utmp struct {
|
||||||
|
Type int16 // Type of login.
|
||||||
|
Pid int32 // Process ID of login process.
|
||||||
|
Line [32]byte // Devicename.
|
||||||
|
ID [4]byte // Inittab ID.
|
||||||
|
User [32]byte // Username.
|
||||||
|
Host [256]byte // Hostname for remote login.
|
||||||
|
Exit exitStatus // Exit status of a process marked
|
||||||
|
Session int32 // Session ID, used for windowing.
|
||||||
|
Tv timeval // Time entry was made.
|
||||||
|
AddrV6 [16]byte // Internet address of remote host.
|
||||||
|
Unused [20]byte // Reserved for future use. // original is 20
|
||||||
|
}
|
61
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux_test.go
generated
vendored
Normal file
61
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_linux_test.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetRedhatishVersion(t *testing.T) {
|
||||||
|
var ret string
|
||||||
|
c := []string{"Rawhide"}
|
||||||
|
ret = getRedhatishVersion(c)
|
||||||
|
if ret != "rawhide" {
|
||||||
|
t.Errorf("Could not get version rawhide: %v", ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
c = []string{"Fedora release 15 (Lovelock)"}
|
||||||
|
ret = getRedhatishVersion(c)
|
||||||
|
if ret != "15" {
|
||||||
|
t.Errorf("Could not get version fedora: %v", ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
c = []string{"Enterprise Linux Server release 5.5 (Carthage)"}
|
||||||
|
ret = getRedhatishVersion(c)
|
||||||
|
if ret != "5.5" {
|
||||||
|
t.Errorf("Could not get version redhat enterprise: %v", ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
c = []string{""}
|
||||||
|
ret = getRedhatishVersion(c)
|
||||||
|
if ret != "" {
|
||||||
|
t.Errorf("Could not get version with no value: %v", ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetRedhatishPlatform(t *testing.T) {
|
||||||
|
var ret string
|
||||||
|
c := []string{"red hat"}
|
||||||
|
ret = getRedhatishPlatform(c)
|
||||||
|
if ret != "redhat" {
|
||||||
|
t.Errorf("Could not get platform redhat: %v", ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
c = []string{"Fedora release 15 (Lovelock)"}
|
||||||
|
ret = getRedhatishPlatform(c)
|
||||||
|
if ret != "fedora" {
|
||||||
|
t.Errorf("Could not get platform fedora: %v", ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
c = []string{"Enterprise Linux Server release 5.5 (Carthage)"}
|
||||||
|
ret = getRedhatishPlatform(c)
|
||||||
|
if ret != "enterprise" {
|
||||||
|
t.Errorf("Could not get platform redhat enterprise: %v", ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
c = []string{""}
|
||||||
|
ret = getRedhatishPlatform(c)
|
||||||
|
if ret != "" {
|
||||||
|
t.Errorf("Could not get platform with no value: %v", ret)
|
||||||
|
}
|
||||||
|
}
|
67
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_test.go
generated
vendored
Normal file
67
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_test.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHostInfo(t *testing.T) {
|
||||||
|
v, err := HostInfo()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
empty := &HostInfoStat{}
|
||||||
|
if v == empty {
|
||||||
|
t.Errorf("Could not get hostinfo %v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBoot_time(t *testing.T) {
|
||||||
|
v, err := BootTime()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
if v == 0 {
|
||||||
|
t.Errorf("Could not get boot time %v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUsers(t *testing.T) {
|
||||||
|
v, err := Users()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
empty := UserStat{}
|
||||||
|
for _, u := range v {
|
||||||
|
if u == empty {
|
||||||
|
t.Errorf("Could not Users %v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHostInfoStat_String(t *testing.T) {
|
||||||
|
v := HostInfoStat{
|
||||||
|
Hostname: "test",
|
||||||
|
Uptime: 3000,
|
||||||
|
Procs: 100,
|
||||||
|
OS: "linux",
|
||||||
|
Platform: "ubuntu",
|
||||||
|
}
|
||||||
|
e := `{"hostname":"test","uptime":3000,"procs":100,"os":"linux","platform":"ubuntu","platform_family":"","platform_version":"","virtualization_system":"","virtualization_role":""}`
|
||||||
|
if e != fmt.Sprintf("%v", v) {
|
||||||
|
t.Errorf("HostInfoStat string is invalid: %v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUserStat_String(t *testing.T) {
|
||||||
|
v := UserStat{
|
||||||
|
User: "user",
|
||||||
|
Terminal: "term",
|
||||||
|
Host: "host",
|
||||||
|
Started: 100,
|
||||||
|
}
|
||||||
|
e := `{"user":"user","terminal":"term","host":"host","started":100}`
|
||||||
|
if e != fmt.Sprintf("%v", v) {
|
||||||
|
t.Errorf("UserStat string is invalid: %v", v)
|
||||||
|
}
|
||||||
|
}
|
123
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_windows.go
generated
vendored
Normal file
123
Godeps/_workspace/src/github.com/shirou/gopsutil/host/host_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/StackExchange/wmi"
|
||||||
|
|
||||||
|
common "github.com/shirou/gopsutil/common"
|
||||||
|
process "github.com/shirou/gopsutil/process"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
procGetSystemTimeAsFileTime = common.Modkernel32.NewProc("GetSystemTimeAsFileTime")
|
||||||
|
osInfo *Win32_OperatingSystem
|
||||||
|
)
|
||||||
|
|
||||||
|
type Win32_OperatingSystem struct {
|
||||||
|
Version string
|
||||||
|
Caption string
|
||||||
|
ProductType uint32
|
||||||
|
BuildNumber string
|
||||||
|
LastBootUpTime time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func HostInfo() (*HostInfoStat, error) {
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := &HostInfoStat{
|
||||||
|
Hostname: hostname,
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
}
|
||||||
|
|
||||||
|
platform, family, version, err := GetPlatformInformation()
|
||||||
|
if err == nil {
|
||||||
|
ret.Platform = platform
|
||||||
|
ret.PlatformFamily = family
|
||||||
|
ret.PlatformVersion = version
|
||||||
|
} else {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.Uptime, err = BootTime()
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
procs, err := process.Pids()
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.Procs = uint64(len(procs))
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOSInfo() (Win32_OperatingSystem, error) {
|
||||||
|
var dst []Win32_OperatingSystem
|
||||||
|
q := wmi.CreateQuery(&dst, "")
|
||||||
|
err := wmi.Query(q, &dst)
|
||||||
|
if err != nil {
|
||||||
|
return Win32_OperatingSystem{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
osInfo = &dst[0]
|
||||||
|
|
||||||
|
return dst[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func BootTime() (uint64, error) {
|
||||||
|
if osInfo == nil {
|
||||||
|
_, err := GetOSInfo()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
now := time.Now()
|
||||||
|
t := osInfo.LastBootUpTime.Local()
|
||||||
|
return uint64(now.Sub(t).Seconds()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPlatformInformation() (platform string, family string, version string, err error) {
|
||||||
|
if osInfo == nil {
|
||||||
|
_, err = GetOSInfo()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Platform
|
||||||
|
platform = strings.Trim(osInfo.Caption, " ")
|
||||||
|
|
||||||
|
// PlatformFamily
|
||||||
|
switch osInfo.ProductType {
|
||||||
|
case 1:
|
||||||
|
family = "Standalone Workstation"
|
||||||
|
case 2:
|
||||||
|
family = "Server (Domain Controller)"
|
||||||
|
case 3:
|
||||||
|
family = "Server"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Platform Version
|
||||||
|
version = fmt.Sprintf("%s Build %s", osInfo.Version, osInfo.BuildNumber)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Users() ([]UserStat, error) {
|
||||||
|
|
||||||
|
var ret []UserStat
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
17
Godeps/_workspace/src/github.com/shirou/gopsutil/host/types_darwin.go
generated
vendored
Normal file
17
Godeps/_workspace/src/github.com/shirou/gopsutil/host/types_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// +build ignore
|
||||||
|
// plus hand editing about timeval
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input to cgo -godefs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <utmpx.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
type Utmpx C.struct_utmpx
|
||||||
|
type Timeval C.struct_timeval
|
43
Godeps/_workspace/src/github.com/shirou/gopsutil/host/types_freebsd.go
generated
vendored
Normal file
43
Godeps/_workspace/src/github.com/shirou/gopsutil/host/types_freebsd.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input to cgo -godefs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define KERNEL
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <utmpx.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
sizeofPtr = sizeof(void*),
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// Machine characteristics; for internal use.
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = C.sizeofPtr
|
||||||
|
sizeofShort = C.sizeof_short
|
||||||
|
sizeofInt = C.sizeof_int
|
||||||
|
sizeofLong = C.sizeof_long
|
||||||
|
sizeofLongLong = C.sizeof_longlong
|
||||||
|
)
|
||||||
|
|
||||||
|
// Basic types
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short C.short
|
||||||
|
_C_int C.int
|
||||||
|
_C_long C.long
|
||||||
|
_C_long_long C.longlong
|
||||||
|
)
|
||||||
|
|
||||||
|
type Utmp C.struct_utmp
|
||||||
|
type Utmpx C.struct_utmpx
|
||||||
|
type Timeval C.struct_timeval
|
45
Godeps/_workspace/src/github.com/shirou/gopsutil/host/types_linux.go
generated
vendored
Normal file
45
Godeps/_workspace/src/github.com/shirou/gopsutil/host/types_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input to cgo -godefs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package host
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define KERNEL
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <utmp.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
sizeofPtr = sizeof(void*),
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// Machine characteristics; for internal use.
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = C.sizeofPtr
|
||||||
|
sizeofShort = C.sizeof_short
|
||||||
|
sizeofInt = C.sizeof_int
|
||||||
|
sizeofLong = C.sizeof_long
|
||||||
|
sizeofLongLong = C.sizeof_longlong
|
||||||
|
)
|
||||||
|
|
||||||
|
// Basic types
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short C.short
|
||||||
|
_C_int C.int
|
||||||
|
_C_long C.long
|
||||||
|
_C_long_long C.longlong
|
||||||
|
)
|
||||||
|
|
||||||
|
type utmp C.struct_utmp
|
||||||
|
type exit_status C.struct_exit_status
|
||||||
|
type UtTv struct {
|
||||||
|
TvSec int32
|
||||||
|
TvUsec int32
|
||||||
|
}
|
634
Godeps/_workspace/src/github.com/shirou/gopsutil/process/binary.go
generated
vendored
Normal file
634
Godeps/_workspace/src/github.com/shirou/gopsutil/process/binary.go
generated
vendored
Normal file
|
@ -0,0 +1,634 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package binary implements simple translation between numbers and byte
|
||||||
|
// sequences and encoding and decoding of varints.
|
||||||
|
//
|
||||||
|
// Numbers are translated by reading and writing fixed-size values.
|
||||||
|
// A fixed-size value is either a fixed-size arithmetic
|
||||||
|
// type (int8, uint8, int16, float32, complex64, ...)
|
||||||
|
// or an array or struct containing only fixed-size values.
|
||||||
|
//
|
||||||
|
// The varint functions encode and decode single integer values using
|
||||||
|
// a variable-length encoding; smaller values require fewer bytes.
|
||||||
|
// For a specification, see
|
||||||
|
// http://code.google.com/apis/protocolbuffers/docs/encoding.html.
|
||||||
|
//
|
||||||
|
// This package favors simplicity over efficiency. Clients that require
|
||||||
|
// high-performance serialization, especially for large data structures,
|
||||||
|
// should look at more advanced solutions such as the encoding/gob
|
||||||
|
// package or protocol buffers.
|
||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A ByteOrder specifies how to convert byte sequences into
|
||||||
|
// 16-, 32-, or 64-bit unsigned integers.
|
||||||
|
type ByteOrder interface {
|
||||||
|
Uint16([]byte) uint16
|
||||||
|
Uint32([]byte) uint32
|
||||||
|
Uint64([]byte) uint64
|
||||||
|
PutUint16([]byte, uint16)
|
||||||
|
PutUint32([]byte, uint32)
|
||||||
|
PutUint64([]byte, uint64)
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// LittleEndian is the little-endian implementation of ByteOrder.
|
||||||
|
var LittleEndian littleEndian
|
||||||
|
|
||||||
|
// BigEndian is the big-endian implementation of ByteOrder.
|
||||||
|
var BigEndian bigEndian
|
||||||
|
|
||||||
|
type littleEndian struct{}
|
||||||
|
|
||||||
|
func (littleEndian) Uint16(b []byte) uint16 { return uint16(b[0]) | uint16(b[1])<<8 }
|
||||||
|
|
||||||
|
func (littleEndian) PutUint16(b []byte, v uint16) {
|
||||||
|
b[0] = byte(v)
|
||||||
|
b[1] = byte(v >> 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (littleEndian) Uint32(b []byte) uint32 {
|
||||||
|
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||||
|
}
|
||||||
|
|
||||||
|
func (littleEndian) PutUint32(b []byte, v uint32) {
|
||||||
|
b[0] = byte(v)
|
||||||
|
b[1] = byte(v >> 8)
|
||||||
|
b[2] = byte(v >> 16)
|
||||||
|
b[3] = byte(v >> 24)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (littleEndian) Uint64(b []byte) uint64 {
|
||||||
|
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
||||||
|
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||||
|
}
|
||||||
|
|
||||||
|
func (littleEndian) PutUint64(b []byte, v uint64) {
|
||||||
|
b[0] = byte(v)
|
||||||
|
b[1] = byte(v >> 8)
|
||||||
|
b[2] = byte(v >> 16)
|
||||||
|
b[3] = byte(v >> 24)
|
||||||
|
b[4] = byte(v >> 32)
|
||||||
|
b[5] = byte(v >> 40)
|
||||||
|
b[6] = byte(v >> 48)
|
||||||
|
b[7] = byte(v >> 56)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (littleEndian) String() string { return "LittleEndian" }
|
||||||
|
|
||||||
|
func (littleEndian) GoString() string { return "binary.LittleEndian" }
|
||||||
|
|
||||||
|
type bigEndian struct{}
|
||||||
|
|
||||||
|
func (bigEndian) Uint16(b []byte) uint16 { return uint16(b[1]) | uint16(b[0])<<8 }
|
||||||
|
|
||||||
|
func (bigEndian) PutUint16(b []byte, v uint16) {
|
||||||
|
b[0] = byte(v >> 8)
|
||||||
|
b[1] = byte(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) Uint32(b []byte) uint32 {
|
||||||
|
return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) PutUint32(b []byte, v uint32) {
|
||||||
|
b[0] = byte(v >> 24)
|
||||||
|
b[1] = byte(v >> 16)
|
||||||
|
b[2] = byte(v >> 8)
|
||||||
|
b[3] = byte(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) Uint64(b []byte) uint64 {
|
||||||
|
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
|
||||||
|
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) PutUint64(b []byte, v uint64) {
|
||||||
|
b[0] = byte(v >> 56)
|
||||||
|
b[1] = byte(v >> 48)
|
||||||
|
b[2] = byte(v >> 40)
|
||||||
|
b[3] = byte(v >> 32)
|
||||||
|
b[4] = byte(v >> 24)
|
||||||
|
b[5] = byte(v >> 16)
|
||||||
|
b[6] = byte(v >> 8)
|
||||||
|
b[7] = byte(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) String() string { return "BigEndian" }
|
||||||
|
|
||||||
|
func (bigEndian) GoString() string { return "binary.BigEndian" }
|
||||||
|
|
||||||
|
// Read reads structured binary data from r into data.
|
||||||
|
// Data must be a pointer to a fixed-size value or a slice
|
||||||
|
// of fixed-size values.
|
||||||
|
// Bytes read from r are decoded using the specified byte order
|
||||||
|
// and written to successive fields of the data.
|
||||||
|
// When reading into structs, the field data for fields with
|
||||||
|
// blank (_) field names is skipped; i.e., blank field names
|
||||||
|
// may be used for padding.
|
||||||
|
// When reading into a struct, all non-blank fields must be exported.
|
||||||
|
func Read(r io.Reader, order ByteOrder, data interface{}) error {
|
||||||
|
// Fast path for basic types and slices.
|
||||||
|
if n := intDataSize(data); n != 0 {
|
||||||
|
var b [8]byte
|
||||||
|
var bs []byte
|
||||||
|
if n > len(b) {
|
||||||
|
bs = make([]byte, n)
|
||||||
|
} else {
|
||||||
|
bs = b[:n]
|
||||||
|
}
|
||||||
|
if _, err := io.ReadFull(r, bs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch data := data.(type) {
|
||||||
|
case *int8:
|
||||||
|
*data = int8(b[0])
|
||||||
|
case *uint8:
|
||||||
|
*data = b[0]
|
||||||
|
case *int16:
|
||||||
|
*data = int16(order.Uint16(bs))
|
||||||
|
case *uint16:
|
||||||
|
*data = order.Uint16(bs)
|
||||||
|
case *int32:
|
||||||
|
*data = int32(order.Uint32(bs))
|
||||||
|
case *uint32:
|
||||||
|
*data = order.Uint32(bs)
|
||||||
|
case *int64:
|
||||||
|
*data = int64(order.Uint64(bs))
|
||||||
|
case *uint64:
|
||||||
|
*data = order.Uint64(bs)
|
||||||
|
case []int8:
|
||||||
|
for i, x := range bs { // Easier to loop over the input for 8-bit values.
|
||||||
|
data[i] = int8(x)
|
||||||
|
}
|
||||||
|
case []uint8:
|
||||||
|
copy(data, bs)
|
||||||
|
case []int16:
|
||||||
|
for i := range data {
|
||||||
|
data[i] = int16(order.Uint16(bs[2*i:]))
|
||||||
|
}
|
||||||
|
case []uint16:
|
||||||
|
for i := range data {
|
||||||
|
data[i] = order.Uint16(bs[2*i:])
|
||||||
|
}
|
||||||
|
case []int32:
|
||||||
|
for i := range data {
|
||||||
|
data[i] = int32(order.Uint32(bs[4*i:]))
|
||||||
|
}
|
||||||
|
case []uint32:
|
||||||
|
for i := range data {
|
||||||
|
data[i] = order.Uint32(bs[4*i:])
|
||||||
|
}
|
||||||
|
case []int64:
|
||||||
|
for i := range data {
|
||||||
|
data[i] = int64(order.Uint64(bs[8*i:]))
|
||||||
|
}
|
||||||
|
case []uint64:
|
||||||
|
for i := range data {
|
||||||
|
data[i] = order.Uint64(bs[8*i:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to reflect-based decoding.
|
||||||
|
v := reflect.ValueOf(data)
|
||||||
|
size := -1
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
v = v.Elem()
|
||||||
|
size = dataSize(v)
|
||||||
|
case reflect.Slice:
|
||||||
|
size = dataSize(v)
|
||||||
|
}
|
||||||
|
if size < 0 {
|
||||||
|
return errors.New("binary.Read: invalid type " + reflect.TypeOf(data).String())
|
||||||
|
}
|
||||||
|
d := &decoder{order: order, buf: make([]byte, size)}
|
||||||
|
if _, err := io.ReadFull(r, d.buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
d.value(v)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write writes the binary representation of data into w.
|
||||||
|
// Data must be a fixed-size value or a slice of fixed-size
|
||||||
|
// values, or a pointer to such data.
|
||||||
|
// Bytes written to w are encoded using the specified byte order
|
||||||
|
// and read from successive fields of the data.
|
||||||
|
// When writing structs, zero values are written for fields
|
||||||
|
// with blank (_) field names.
|
||||||
|
func Write(w io.Writer, order ByteOrder, data interface{}) error {
|
||||||
|
// Fast path for basic types and slices.
|
||||||
|
if n := intDataSize(data); n != 0 {
|
||||||
|
var b [8]byte
|
||||||
|
var bs []byte
|
||||||
|
if n > len(b) {
|
||||||
|
bs = make([]byte, n)
|
||||||
|
} else {
|
||||||
|
bs = b[:n]
|
||||||
|
}
|
||||||
|
switch v := data.(type) {
|
||||||
|
case *int8:
|
||||||
|
bs = b[:1]
|
||||||
|
b[0] = byte(*v)
|
||||||
|
case int8:
|
||||||
|
bs = b[:1]
|
||||||
|
b[0] = byte(v)
|
||||||
|
case []int8:
|
||||||
|
for i, x := range v {
|
||||||
|
bs[i] = byte(x)
|
||||||
|
}
|
||||||
|
case *uint8:
|
||||||
|
bs = b[:1]
|
||||||
|
b[0] = *v
|
||||||
|
case uint8:
|
||||||
|
bs = b[:1]
|
||||||
|
b[0] = byte(v)
|
||||||
|
case []uint8:
|
||||||
|
bs = v
|
||||||
|
case *int16:
|
||||||
|
bs = b[:2]
|
||||||
|
order.PutUint16(bs, uint16(*v))
|
||||||
|
case int16:
|
||||||
|
bs = b[:2]
|
||||||
|
order.PutUint16(bs, uint16(v))
|
||||||
|
case []int16:
|
||||||
|
for i, x := range v {
|
||||||
|
order.PutUint16(bs[2*i:], uint16(x))
|
||||||
|
}
|
||||||
|
case *uint16:
|
||||||
|
bs = b[:2]
|
||||||
|
order.PutUint16(bs, *v)
|
||||||
|
case uint16:
|
||||||
|
bs = b[:2]
|
||||||
|
order.PutUint16(bs, v)
|
||||||
|
case []uint16:
|
||||||
|
for i, x := range v {
|
||||||
|
order.PutUint16(bs[2*i:], x)
|
||||||
|
}
|
||||||
|
case *int32:
|
||||||
|
bs = b[:4]
|
||||||
|
order.PutUint32(bs, uint32(*v))
|
||||||
|
case int32:
|
||||||
|
bs = b[:4]
|
||||||
|
order.PutUint32(bs, uint32(v))
|
||||||
|
case []int32:
|
||||||
|
for i, x := range v {
|
||||||
|
order.PutUint32(bs[4*i:], uint32(x))
|
||||||
|
}
|
||||||
|
case *uint32:
|
||||||
|
bs = b[:4]
|
||||||
|
order.PutUint32(bs, *v)
|
||||||
|
case uint32:
|
||||||
|
bs = b[:4]
|
||||||
|
order.PutUint32(bs, v)
|
||||||
|
case []uint32:
|
||||||
|
for i, x := range v {
|
||||||
|
order.PutUint32(bs[4*i:], x)
|
||||||
|
}
|
||||||
|
case *int64:
|
||||||
|
bs = b[:8]
|
||||||
|
order.PutUint64(bs, uint64(*v))
|
||||||
|
case int64:
|
||||||
|
bs = b[:8]
|
||||||
|
order.PutUint64(bs, uint64(v))
|
||||||
|
case []int64:
|
||||||
|
for i, x := range v {
|
||||||
|
order.PutUint64(bs[8*i:], uint64(x))
|
||||||
|
}
|
||||||
|
case *uint64:
|
||||||
|
bs = b[:8]
|
||||||
|
order.PutUint64(bs, *v)
|
||||||
|
case uint64:
|
||||||
|
bs = b[:8]
|
||||||
|
order.PutUint64(bs, v)
|
||||||
|
case []uint64:
|
||||||
|
for i, x := range v {
|
||||||
|
order.PutUint64(bs[8*i:], x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err := w.Write(bs)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to reflect-based encoding.
|
||||||
|
v := reflect.Indirect(reflect.ValueOf(data))
|
||||||
|
size := dataSize(v)
|
||||||
|
if size < 0 {
|
||||||
|
return errors.New("binary.Write: invalid type " + reflect.TypeOf(data).String())
|
||||||
|
}
|
||||||
|
buf := make([]byte, size)
|
||||||
|
e := &encoder{order: order, buf: buf}
|
||||||
|
e.value(v)
|
||||||
|
_, err := w.Write(buf)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size returns how many bytes Write would generate to encode the value v, which
|
||||||
|
// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.
|
||||||
|
// If v is neither of these, Size returns -1.
|
||||||
|
func Size(v interface{}) int {
|
||||||
|
return dataSize(reflect.Indirect(reflect.ValueOf(v)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// dataSize returns the number of bytes the actual data represented by v occupies in memory.
|
||||||
|
// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice
|
||||||
|
// it returns the length of the slice times the element size and does not count the memory
|
||||||
|
// occupied by the header. If the type of v is not acceptable, dataSize returns -1.
|
||||||
|
func dataSize(v reflect.Value) int {
|
||||||
|
if v.Kind() == reflect.Slice {
|
||||||
|
if s := sizeof(v.Type().Elem()); s >= 0 {
|
||||||
|
return s * v.Len()
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return sizeof(v.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.
|
||||||
|
func sizeof(t reflect.Type) int {
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Array:
|
||||||
|
if s := sizeof(t.Elem()); s >= 0 {
|
||||||
|
return s * t.Len()
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Struct:
|
||||||
|
sum := 0
|
||||||
|
for i, n := 0, t.NumField(); i < n; i++ {
|
||||||
|
s := sizeof(t.Field(i).Type)
|
||||||
|
if s < 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
sum += s
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
|
||||||
|
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||||
|
reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||||
|
reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Ptr:
|
||||||
|
return int(t.Size())
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
type coder struct {
|
||||||
|
order ByteOrder
|
||||||
|
buf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type decoder coder
|
||||||
|
type encoder coder
|
||||||
|
|
||||||
|
func (d *decoder) uint8() uint8 {
|
||||||
|
x := d.buf[0]
|
||||||
|
d.buf = d.buf[1:]
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) uint8(x uint8) {
|
||||||
|
e.buf[0] = x
|
||||||
|
e.buf = e.buf[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) uint16() uint16 {
|
||||||
|
x := d.order.Uint16(d.buf[0:2])
|
||||||
|
d.buf = d.buf[2:]
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) uint16(x uint16) {
|
||||||
|
e.order.PutUint16(e.buf[0:2], x)
|
||||||
|
e.buf = e.buf[2:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) uint32() uint32 {
|
||||||
|
x := d.order.Uint32(d.buf[0:4])
|
||||||
|
d.buf = d.buf[4:]
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) uint32(x uint32) {
|
||||||
|
e.order.PutUint32(e.buf[0:4], x)
|
||||||
|
e.buf = e.buf[4:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) uint64() uint64 {
|
||||||
|
x := d.order.Uint64(d.buf[0:8])
|
||||||
|
d.buf = d.buf[8:]
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) uint64(x uint64) {
|
||||||
|
e.order.PutUint64(e.buf[0:8], x)
|
||||||
|
e.buf = e.buf[8:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) int8() int8 { return int8(d.uint8()) }
|
||||||
|
|
||||||
|
func (e *encoder) int8(x int8) { e.uint8(uint8(x)) }
|
||||||
|
|
||||||
|
func (d *decoder) int16() int16 { return int16(d.uint16()) }
|
||||||
|
|
||||||
|
func (e *encoder) int16(x int16) { e.uint16(uint16(x)) }
|
||||||
|
|
||||||
|
func (d *decoder) int32() int32 { return int32(d.uint32()) }
|
||||||
|
|
||||||
|
func (e *encoder) int32(x int32) { e.uint32(uint32(x)) }
|
||||||
|
|
||||||
|
func (d *decoder) int64() int64 { return int64(d.uint64()) }
|
||||||
|
|
||||||
|
func (e *encoder) int64(x int64) { e.uint64(uint64(x)) }
|
||||||
|
|
||||||
|
func (d *decoder) value(v reflect.Value) {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Array:
|
||||||
|
l := v.Len()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
d.value(v.Index(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Struct:
|
||||||
|
t := v.Type()
|
||||||
|
l := v.NumField()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
// Note: Calling v.CanSet() below is an optimization.
|
||||||
|
// It would be sufficient to check the field name,
|
||||||
|
// but creating the StructField info for each field is
|
||||||
|
// costly (run "go test -bench=ReadStruct" and compare
|
||||||
|
// results when making changes to this code).
|
||||||
|
if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
|
||||||
|
d.value(v)
|
||||||
|
} else {
|
||||||
|
d.skip(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Slice:
|
||||||
|
l := v.Len()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
d.value(v.Index(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Int8:
|
||||||
|
v.SetInt(int64(d.int8()))
|
||||||
|
case reflect.Int16:
|
||||||
|
v.SetInt(int64(d.int16()))
|
||||||
|
case reflect.Int32:
|
||||||
|
v.SetInt(int64(d.int32()))
|
||||||
|
case reflect.Int64:
|
||||||
|
v.SetInt(d.int64())
|
||||||
|
|
||||||
|
case reflect.Uint8:
|
||||||
|
v.SetUint(uint64(d.uint8()))
|
||||||
|
case reflect.Uint16:
|
||||||
|
v.SetUint(uint64(d.uint16()))
|
||||||
|
case reflect.Uint32:
|
||||||
|
v.SetUint(uint64(d.uint32()))
|
||||||
|
case reflect.Uint64:
|
||||||
|
v.SetUint(d.uint64())
|
||||||
|
|
||||||
|
case reflect.Float32:
|
||||||
|
v.SetFloat(float64(math.Float32frombits(d.uint32())))
|
||||||
|
case reflect.Float64:
|
||||||
|
v.SetFloat(math.Float64frombits(d.uint64()))
|
||||||
|
|
||||||
|
case reflect.Complex64:
|
||||||
|
v.SetComplex(complex(
|
||||||
|
float64(math.Float32frombits(d.uint32())),
|
||||||
|
float64(math.Float32frombits(d.uint32())),
|
||||||
|
))
|
||||||
|
case reflect.Complex128:
|
||||||
|
v.SetComplex(complex(
|
||||||
|
math.Float64frombits(d.uint64()),
|
||||||
|
math.Float64frombits(d.uint64()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) value(v reflect.Value) {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Array:
|
||||||
|
l := v.Len()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
e.value(v.Index(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Struct:
|
||||||
|
t := v.Type()
|
||||||
|
l := v.NumField()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
// see comment for corresponding code in decoder.value()
|
||||||
|
if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
|
||||||
|
e.value(v)
|
||||||
|
} else {
|
||||||
|
e.skip(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Slice:
|
||||||
|
l := v.Len()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
e.value(v.Index(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
switch v.Type().Kind() {
|
||||||
|
case reflect.Int8:
|
||||||
|
e.int8(int8(v.Int()))
|
||||||
|
case reflect.Int16:
|
||||||
|
e.int16(int16(v.Int()))
|
||||||
|
case reflect.Int32:
|
||||||
|
e.int32(int32(v.Int()))
|
||||||
|
case reflect.Int64:
|
||||||
|
e.int64(v.Int())
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
switch v.Type().Kind() {
|
||||||
|
case reflect.Uint8:
|
||||||
|
e.uint8(uint8(v.Uint()))
|
||||||
|
case reflect.Uint16:
|
||||||
|
e.uint16(uint16(v.Uint()))
|
||||||
|
case reflect.Uint32:
|
||||||
|
e.uint32(uint32(v.Uint()))
|
||||||
|
case reflect.Uint64:
|
||||||
|
e.uint64(v.Uint())
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
switch v.Type().Kind() {
|
||||||
|
case reflect.Float32:
|
||||||
|
e.uint32(math.Float32bits(float32(v.Float())))
|
||||||
|
case reflect.Float64:
|
||||||
|
e.uint64(math.Float64bits(v.Float()))
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
switch v.Type().Kind() {
|
||||||
|
case reflect.Complex64:
|
||||||
|
x := v.Complex()
|
||||||
|
e.uint32(math.Float32bits(float32(real(x))))
|
||||||
|
e.uint32(math.Float32bits(float32(imag(x))))
|
||||||
|
case reflect.Complex128:
|
||||||
|
x := v.Complex()
|
||||||
|
e.uint64(math.Float64bits(real(x)))
|
||||||
|
e.uint64(math.Float64bits(imag(x)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) skip(v reflect.Value) {
|
||||||
|
d.buf = d.buf[dataSize(v):]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) skip(v reflect.Value) {
|
||||||
|
n := dataSize(v)
|
||||||
|
for i := range e.buf[0:n] {
|
||||||
|
e.buf[i] = 0
|
||||||
|
}
|
||||||
|
e.buf = e.buf[n:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// intDataSize returns the size of the data required to represent the data when encoded.
|
||||||
|
// It returns zero if the type cannot be implemented by the fast path in Read or Write.
|
||||||
|
func intDataSize(data interface{}) int {
|
||||||
|
switch data := data.(type) {
|
||||||
|
case int8, *int8, *uint8:
|
||||||
|
return 1
|
||||||
|
case []int8:
|
||||||
|
return len(data)
|
||||||
|
case []uint8:
|
||||||
|
return len(data)
|
||||||
|
case int16, *int16, *uint16:
|
||||||
|
return 2
|
||||||
|
case []int16:
|
||||||
|
return 2 * len(data)
|
||||||
|
case []uint16:
|
||||||
|
return 2 * len(data)
|
||||||
|
case int32, *int32, *uint32:
|
||||||
|
return 4
|
||||||
|
case []int32:
|
||||||
|
return 4 * len(data)
|
||||||
|
case []uint32:
|
||||||
|
return 4 * len(data)
|
||||||
|
case int64, *int64, *uint64:
|
||||||
|
return 8
|
||||||
|
case []int64:
|
||||||
|
return 8 * len(data)
|
||||||
|
case []uint64:
|
||||||
|
return 8 * len(data)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
10
Godeps/_workspace/src/github.com/shirou/gopsutil/process/expected/darwin/%2Fbin%2Fps-x-opid_fail
generated
vendored
Normal file
10
Godeps/_workspace/src/github.com/shirou/gopsutil/process/expected/darwin/%2Fbin%2Fps-x-opid_fail
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
PID
|
||||||
|
245
|
||||||
|
247
|
||||||
|
248
|
||||||
|
249
|
||||||
|
254
|
||||||
|
262
|
||||||
|
264
|
||||||
|
265
|
||||||
|
267
|
149
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process.go
generated
vendored
Normal file
149
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process.go
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"runtime"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/common"
|
||||||
|
"github.com/shirou/gopsutil/cpu"
|
||||||
|
)
|
||||||
|
|
||||||
|
var invoke common.Invoker
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
invoke = common.Invoke{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Process struct {
|
||||||
|
Pid int32 `json:"pid"`
|
||||||
|
name string
|
||||||
|
status string
|
||||||
|
numCtxSwitches *NumCtxSwitchesStat
|
||||||
|
uids []int32
|
||||||
|
gids []int32
|
||||||
|
numThreads int32
|
||||||
|
memInfo *MemoryInfoStat
|
||||||
|
|
||||||
|
lastCPUTimes *cpu.CPUTimesStat
|
||||||
|
lastCPUTime time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type OpenFilesStat struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
Fd uint64 `json:"fd"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MemoryInfoStat struct {
|
||||||
|
RSS uint64 `json:"rss"` // bytes
|
||||||
|
VMS uint64 `json:"vms"` // bytes
|
||||||
|
Swap uint64 `json:"swap"` // bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
type RlimitStat struct {
|
||||||
|
Resource int32 `json:"resource"`
|
||||||
|
Soft int32 `json:"soft"`
|
||||||
|
Hard int32 `json:"hard"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IOCountersStat struct {
|
||||||
|
ReadCount uint64 `json:"read_count"`
|
||||||
|
WriteCount uint64 `json:"write_count"`
|
||||||
|
ReadBytes uint64 `json:"read_bytes"`
|
||||||
|
WriteBytes uint64 `json:"write_bytes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NumCtxSwitchesStat struct {
|
||||||
|
Voluntary int64 `json:"voluntary"`
|
||||||
|
Involuntary int64 `json:"involuntary"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Process) String() string {
|
||||||
|
s, _ := json.Marshal(p)
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o OpenFilesStat) String() string {
|
||||||
|
s, _ := json.Marshal(o)
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MemoryInfoStat) String() string {
|
||||||
|
s, _ := json.Marshal(m)
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RlimitStat) String() string {
|
||||||
|
s, _ := json.Marshal(r)
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i IOCountersStat) String() string {
|
||||||
|
s, _ := json.Marshal(i)
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p NumCtxSwitchesStat) String() string {
|
||||||
|
s, _ := json.Marshal(p)
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PidExists(pid int32) (bool, error) {
|
||||||
|
pids, err := Pids()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, i := range pids {
|
||||||
|
if i == pid {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If interval is 0, return difference from last call(non-blocking).
|
||||||
|
// If interval > 0, wait interval sec and return diffrence between start and end.
|
||||||
|
func (p *Process) CPUPercent(interval time.Duration) (float64, error) {
|
||||||
|
numcpu := runtime.NumCPU()
|
||||||
|
calculate := func(t1, t2 *cpu.CPUTimesStat, delta float64) float64 {
|
||||||
|
if delta == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
delta_proc := (t2.User - t1.User) + (t2.System - t1.System)
|
||||||
|
overall_percent := ((delta_proc / delta) * 100) * float64(numcpu)
|
||||||
|
return overall_percent
|
||||||
|
}
|
||||||
|
|
||||||
|
cpuTimes, err := p.CPUTimes()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if interval > 0 {
|
||||||
|
p.lastCPUTimes = cpuTimes
|
||||||
|
p.lastCPUTime = time.Now()
|
||||||
|
time.Sleep(interval)
|
||||||
|
cpuTimes, err = p.CPUTimes()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if p.lastCPUTimes == nil {
|
||||||
|
// invoked first time
|
||||||
|
p.lastCPUTimes, err = p.CPUTimes()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
p.lastCPUTime = time.Now()
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delta := (time.Now().Sub(p.lastCPUTime).Seconds()) * float64(numcpu)
|
||||||
|
ret := calculate(p.lastCPUTimes, cpuTimes, float64(delta))
|
||||||
|
p.lastCPUTimes = cpuTimes
|
||||||
|
p.lastCPUTime = time.Now()
|
||||||
|
return ret, nil
|
||||||
|
}
|
421
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_darwin.go
generated
vendored
Normal file
421
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,421 @@
|
||||||
|
// +build darwin
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/common"
|
||||||
|
"github.com/shirou/gopsutil/cpu"
|
||||||
|
"github.com/shirou/gopsutil/net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// copied from sys/sysctl.h
|
||||||
|
const (
|
||||||
|
CTLKern = 1 // "high kernel": proc, limits
|
||||||
|
KernProc = 14 // struct: process entries
|
||||||
|
KernProcPID = 1 // by process id
|
||||||
|
KernProcProc = 8 // only return procs
|
||||||
|
KernProcAll = 0 // everything
|
||||||
|
KernProcPathname = 12 // path to executable
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ClockTicks = 100 // C.sysconf(C._SC_CLK_TCK)
|
||||||
|
)
|
||||||
|
|
||||||
|
type _Ctype_struct___0 struct {
|
||||||
|
Pad uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// MemoryInfoExStat is different between OSes
|
||||||
|
type MemoryInfoExStat struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type MemoryMapsStat struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func Pids() ([]int32, error) {
|
||||||
|
var ret []int32
|
||||||
|
|
||||||
|
pids, err := callPs("pid", 0, false)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pid := range pids {
|
||||||
|
v, err := strconv.Atoi(pid[0])
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
ret = append(ret, int32(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Ppid() (int32, error) {
|
||||||
|
r, err := callPs("ppid", p.Pid, false)
|
||||||
|
v, err := strconv.Atoi(r[0][0])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return int32(v), err
|
||||||
|
}
|
||||||
|
func (p *Process) Name() (string, error) {
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return common.IntToString(k.Proc.P_comm[:]), nil
|
||||||
|
}
|
||||||
|
func (p *Process) Exe() (string, error) {
|
||||||
|
return "", common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Cmdline() (string, error) {
|
||||||
|
r, err := callPs("command", p.Pid, false)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return strings.Join(r[0], " "), err
|
||||||
|
}
|
||||||
|
func (p *Process) CreateTime() (int64, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Cwd() (string, error) {
|
||||||
|
return "", common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Parent() (*Process, error) {
|
||||||
|
rr, err := common.CallLsof(invoke, p.Pid, "-FR")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, r := range rr {
|
||||||
|
if strings.HasPrefix(r, "p") { // skip if process
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
l := string(r)
|
||||||
|
v, err := strconv.Atoi(strings.Replace(l, "R", "", 1))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewProcess(int32(v))
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("could not find parent line")
|
||||||
|
}
|
||||||
|
func (p *Process) Status() (string, error) {
|
||||||
|
r, err := callPs("state", p.Pid, false)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r[0][0], err
|
||||||
|
}
|
||||||
|
func (p *Process) Uids() ([]int32, error) {
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
uids := make([]int32, 0, 3)
|
||||||
|
|
||||||
|
uids = append(uids, int32(k.Eproc.Pcred.P_ruid), int32(k.Eproc.Ucred.Uid), int32(k.Eproc.Pcred.P_svuid))
|
||||||
|
|
||||||
|
return uids, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Gids() ([]int32, error) {
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
gids := make([]int32, 0, 3)
|
||||||
|
gids = append(gids, int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Ucred.Ngroups), int32(k.Eproc.Pcred.P_svgid))
|
||||||
|
|
||||||
|
return gids, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Terminal() (string, error) {
|
||||||
|
return "", common.NotImplementedError
|
||||||
|
/*
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
ttyNr := uint64(k.Eproc.Tdev)
|
||||||
|
termmap, err := getTerminalMap()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return termmap[ttyNr], nil
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
func (p *Process) Nice() (int32, error) {
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return int32(k.Proc.P_nice), nil
|
||||||
|
}
|
||||||
|
func (p *Process) IOnice() (int32, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Rlimit() ([]RlimitStat, error) {
|
||||||
|
var rlimit []RlimitStat
|
||||||
|
return rlimit, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) IOCounters() (*IOCountersStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) NumFDs() (int32, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) NumThreads() (int32, error) {
|
||||||
|
r, err := callPs("utime,stime", p.Pid, true)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return int32(len(r)), nil
|
||||||
|
}
|
||||||
|
func (p *Process) Threads() (map[string]string, error) {
|
||||||
|
ret := make(map[string]string, 0)
|
||||||
|
return ret, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertCpuTimes(s string) (ret float64, err error) {
|
||||||
|
var t int
|
||||||
|
var _tmp string
|
||||||
|
if strings.Contains(s, ":") {
|
||||||
|
_t := strings.Split(s, ":")
|
||||||
|
hour, err := strconv.Atoi(_t[0])
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
t += hour * 60 * 100
|
||||||
|
_tmp = _t[1]
|
||||||
|
} else {
|
||||||
|
_tmp = s
|
||||||
|
}
|
||||||
|
|
||||||
|
_t := strings.Split(_tmp, ".")
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
h, err := strconv.Atoi(_t[0])
|
||||||
|
t += h * 100
|
||||||
|
h, err = strconv.Atoi(_t[1])
|
||||||
|
t += h
|
||||||
|
return float64(t) / ClockTicks, nil
|
||||||
|
}
|
||||||
|
func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) {
|
||||||
|
r, err := callPs("utime,stime", p.Pid, false)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
utime, err := convertCpuTimes(r[0][0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
stime, err := convertCpuTimes(r[0][1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := &cpu.CPUTimesStat{
|
||||||
|
CPU: "cpu",
|
||||||
|
User: utime,
|
||||||
|
System: stime,
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
func (p *Process) CPUAffinity() ([]int32, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
|
||||||
|
r, err := callPs("rss,vsize,pagein", p.Pid, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rss, err := strconv.Atoi(r[0][0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
vms, err := strconv.Atoi(r[0][1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pagein, err := strconv.Atoi(r[0][2])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := &MemoryInfoStat{
|
||||||
|
RSS: uint64(rss),
|
||||||
|
VMS: uint64(vms),
|
||||||
|
Swap: uint64(pagein),
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryPercent() (float32, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Children() ([]*Process, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Connections() ([]net.NetConnectionStat, error) {
|
||||||
|
return net.NetConnectionsPid("all", p.Pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) IsRunning() (bool, error) {
|
||||||
|
return true, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
|
||||||
|
var ret []MemoryMapsStat
|
||||||
|
return &ret, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyParams(k *KinfoProc, p *Process) error {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func processes() ([]Process, error) {
|
||||||
|
results := make([]Process, 0, 50)
|
||||||
|
|
||||||
|
mib := []int32{CTLKern, KernProc, KernProcAll, 0}
|
||||||
|
buf, length, err := common.CallSyscall(mib)
|
||||||
|
if err != nil {
|
||||||
|
return results, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// get kinfo_proc size
|
||||||
|
k := KinfoProc{}
|
||||||
|
procinfoLen := int(unsafe.Sizeof(k))
|
||||||
|
count := int(length / uint64(procinfoLen))
|
||||||
|
/*
|
||||||
|
fmt.Println(length, procinfoLen, count)
|
||||||
|
b := buf[0*procinfoLen : 0*procinfoLen+procinfoLen]
|
||||||
|
fmt.Println(b)
|
||||||
|
kk, err := parseKinfoProc(b)
|
||||||
|
fmt.Printf("%#v", kk)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// parse buf to procs
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
b := buf[i*procinfoLen : i*procinfoLen+procinfoLen]
|
||||||
|
k, err := parseKinfoProc(b)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p, err := NewProcess(int32(k.Proc.P_pid))
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
copyParams(&k, p)
|
||||||
|
|
||||||
|
results = append(results, *p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseKinfoProc(buf []byte) (KinfoProc, error) {
|
||||||
|
var k KinfoProc
|
||||||
|
br := bytes.NewReader(buf)
|
||||||
|
|
||||||
|
err := Read(br, LittleEndian, &k)
|
||||||
|
if err != nil {
|
||||||
|
return k, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return k, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) getKProc() (*KinfoProc, error) {
|
||||||
|
mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid}
|
||||||
|
procK := KinfoProc{}
|
||||||
|
length := uint64(unsafe.Sizeof(procK))
|
||||||
|
buf := make([]byte, length)
|
||||||
|
_, _, syserr := syscall.Syscall6(
|
||||||
|
syscall.SYS___SYSCTL,
|
||||||
|
uintptr(unsafe.Pointer(&mib[0])),
|
||||||
|
uintptr(len(mib)),
|
||||||
|
uintptr(unsafe.Pointer(&buf[0])),
|
||||||
|
uintptr(unsafe.Pointer(&length)),
|
||||||
|
0,
|
||||||
|
0)
|
||||||
|
if syserr != 0 {
|
||||||
|
return nil, syserr
|
||||||
|
}
|
||||||
|
k, err := parseKinfoProc(buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &k, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProcess(pid int32) (*Process, error) {
|
||||||
|
p := &Process{Pid: pid}
|
||||||
|
|
||||||
|
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.
|
||||||
|
// If passed arg pid is 0, get information from all process.
|
||||||
|
func callPs(arg string, pid int32, threadOption bool) ([][]string, error) {
|
||||||
|
var cmd []string
|
||||||
|
if pid == 0 { // will get from all processes.
|
||||||
|
cmd = []string{"-x", "-o", arg}
|
||||||
|
} else if threadOption {
|
||||||
|
cmd = []string{"-x", "-o", arg, "-M", "-p", strconv.Itoa(int(pid))}
|
||||||
|
} else {
|
||||||
|
cmd = []string{"-x", "-o", arg, "-p", strconv.Itoa(int(pid))}
|
||||||
|
}
|
||||||
|
out, err := invoke.Command("/bin/ps", cmd...)
|
||||||
|
if err != nil {
|
||||||
|
return [][]string{}, err
|
||||||
|
}
|
||||||
|
lines := strings.Split(string(out), "\n")
|
||||||
|
|
||||||
|
var ret [][]string
|
||||||
|
for _, l := range lines[1:] {
|
||||||
|
var lr []string
|
||||||
|
for _, r := range strings.Split(l, " ") {
|
||||||
|
if r == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lr = append(lr, strings.TrimSpace(r))
|
||||||
|
}
|
||||||
|
if len(lr) != 0 {
|
||||||
|
ret = append(ret, lr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
234
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_darwin_amd64.go
generated
vendored
Normal file
234
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_darwin_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
// Created by cgo -godefs - DO NOT EDIT
|
||||||
|
// cgo -godefs types_darwin.go
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x8
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x8
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short int16
|
||||||
|
_C_int int32
|
||||||
|
_C_long int64
|
||||||
|
_C_long_long int64
|
||||||
|
)
|
||||||
|
|
||||||
|
type Timespec struct {
|
||||||
|
Sec int64
|
||||||
|
Nsec int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type Timeval struct {
|
||||||
|
Sec int64
|
||||||
|
Usec int32
|
||||||
|
Pad_cgo_0 [4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type Rusage struct {
|
||||||
|
Utime Timeval
|
||||||
|
Stime Timeval
|
||||||
|
Maxrss int64
|
||||||
|
Ixrss int64
|
||||||
|
Idrss int64
|
||||||
|
Isrss int64
|
||||||
|
Minflt int64
|
||||||
|
Majflt int64
|
||||||
|
Nswap int64
|
||||||
|
Inblock int64
|
||||||
|
Oublock int64
|
||||||
|
Msgsnd int64
|
||||||
|
Msgrcv int64
|
||||||
|
Nsignals int64
|
||||||
|
Nvcsw int64
|
||||||
|
Nivcsw int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type Rlimit struct {
|
||||||
|
Cur uint64
|
||||||
|
Max uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type UGid_t uint32
|
||||||
|
|
||||||
|
type KinfoProc struct {
|
||||||
|
Proc ExternProc
|
||||||
|
Eproc Eproc
|
||||||
|
}
|
||||||
|
|
||||||
|
type Eproc struct {
|
||||||
|
Paddr *uint64
|
||||||
|
Sess *Session
|
||||||
|
Pcred Upcred
|
||||||
|
Ucred Uucred
|
||||||
|
Pad_cgo_0 [4]byte
|
||||||
|
Vm Vmspace
|
||||||
|
Ppid int32
|
||||||
|
Pgid int32
|
||||||
|
Jobc int16
|
||||||
|
Pad_cgo_1 [2]byte
|
||||||
|
Tdev int32
|
||||||
|
Tpgid int32
|
||||||
|
Pad_cgo_2 [4]byte
|
||||||
|
Tsess *Session
|
||||||
|
Wmesg [8]int8
|
||||||
|
Xsize int32
|
||||||
|
Xrssize int16
|
||||||
|
Xccount int16
|
||||||
|
Xswrss int16
|
||||||
|
Pad_cgo_3 [2]byte
|
||||||
|
Flag int32
|
||||||
|
Login [12]int8
|
||||||
|
Spare [4]int32
|
||||||
|
Pad_cgo_4 [4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type Proc struct{}
|
||||||
|
|
||||||
|
type Session struct{}
|
||||||
|
|
||||||
|
type ucred struct {
|
||||||
|
Link _Ctype_struct___0
|
||||||
|
Ref uint64
|
||||||
|
Posix Posix_cred
|
||||||
|
Label *Label
|
||||||
|
Audit Au_session
|
||||||
|
}
|
||||||
|
|
||||||
|
type Uucred struct {
|
||||||
|
Ref int32
|
||||||
|
Uid uint32
|
||||||
|
Ngroups int16
|
||||||
|
Pad_cgo_0 [2]byte
|
||||||
|
Groups [16]uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type Upcred struct {
|
||||||
|
Pc_lock [72]int8
|
||||||
|
Pc_ucred *ucred
|
||||||
|
P_ruid uint32
|
||||||
|
P_svuid uint32
|
||||||
|
P_rgid uint32
|
||||||
|
P_svgid uint32
|
||||||
|
P_refcnt int32
|
||||||
|
Pad_cgo_0 [4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type Vmspace struct {
|
||||||
|
Dummy int32
|
||||||
|
Pad_cgo_0 [4]byte
|
||||||
|
Dummy2 *int8
|
||||||
|
Dummy3 [5]int32
|
||||||
|
Pad_cgo_1 [4]byte
|
||||||
|
Dummy4 [3]*int8
|
||||||
|
}
|
||||||
|
|
||||||
|
type Sigacts struct{}
|
||||||
|
|
||||||
|
type ExternProc struct {
|
||||||
|
P_un [16]byte
|
||||||
|
P_vmspace uint64
|
||||||
|
P_sigacts uint64
|
||||||
|
Pad_cgo_0 [3]byte
|
||||||
|
P_flag int32
|
||||||
|
P_stat int8
|
||||||
|
P_pid int32
|
||||||
|
P_oppid int32
|
||||||
|
P_dupfd int32
|
||||||
|
Pad_cgo_1 [4]byte
|
||||||
|
User_stack uint64
|
||||||
|
Exit_thread uint64
|
||||||
|
P_debugger int32
|
||||||
|
Sigwait int32
|
||||||
|
P_estcpu uint32
|
||||||
|
P_cpticks int32
|
||||||
|
P_pctcpu uint32
|
||||||
|
Pad_cgo_2 [4]byte
|
||||||
|
P_wchan uint64
|
||||||
|
P_wmesg uint64
|
||||||
|
P_swtime uint32
|
||||||
|
P_slptime uint32
|
||||||
|
P_realtimer Itimerval
|
||||||
|
P_rtime Timeval
|
||||||
|
P_uticks uint64
|
||||||
|
P_sticks uint64
|
||||||
|
P_iticks uint64
|
||||||
|
P_traceflag int32
|
||||||
|
Pad_cgo_3 [4]byte
|
||||||
|
P_tracep uint64
|
||||||
|
P_siglist int32
|
||||||
|
Pad_cgo_4 [4]byte
|
||||||
|
P_textvp uint64
|
||||||
|
P_holdcnt int32
|
||||||
|
P_sigmask uint32
|
||||||
|
P_sigignore uint32
|
||||||
|
P_sigcatch uint32
|
||||||
|
P_priority uint8
|
||||||
|
P_usrpri uint8
|
||||||
|
P_nice int8
|
||||||
|
P_comm [17]int8
|
||||||
|
Pad_cgo_5 [4]byte
|
||||||
|
P_pgrp uint64
|
||||||
|
P_addr uint64
|
||||||
|
P_xstat uint16
|
||||||
|
P_acflag uint16
|
||||||
|
Pad_cgo_6 [4]byte
|
||||||
|
P_ru uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type Itimerval struct {
|
||||||
|
Interval Timeval
|
||||||
|
Value Timeval
|
||||||
|
}
|
||||||
|
|
||||||
|
type Vnode struct{}
|
||||||
|
|
||||||
|
type Pgrp struct{}
|
||||||
|
|
||||||
|
type UserStruct struct{}
|
||||||
|
|
||||||
|
type Au_session struct {
|
||||||
|
Aia_p *AuditinfoAddr
|
||||||
|
Mask AuMask
|
||||||
|
}
|
||||||
|
|
||||||
|
type Posix_cred struct {
|
||||||
|
Uid uint32
|
||||||
|
Ruid uint32
|
||||||
|
Svuid uint32
|
||||||
|
Ngroups int16
|
||||||
|
Pad_cgo_0 [2]byte
|
||||||
|
Groups [16]uint32
|
||||||
|
Rgid uint32
|
||||||
|
Svgid uint32
|
||||||
|
Gmuid uint32
|
||||||
|
Flags int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type Label struct{}
|
||||||
|
|
||||||
|
type AuditinfoAddr struct {
|
||||||
|
Auid uint32
|
||||||
|
Mask AuMask
|
||||||
|
Termid AuTidAddr
|
||||||
|
Asid int32
|
||||||
|
Flags uint64
|
||||||
|
}
|
||||||
|
type AuMask struct {
|
||||||
|
Success uint32
|
||||||
|
Failure uint32
|
||||||
|
}
|
||||||
|
type AuTidAddr struct {
|
||||||
|
Port int32
|
||||||
|
Type uint32
|
||||||
|
Addr [4]uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type UcredQueue struct {
|
||||||
|
Next *ucred
|
||||||
|
Prev **ucred
|
||||||
|
}
|
263
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd.go
generated
vendored
Normal file
263
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd.go
generated
vendored
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
// +build freebsd
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
common "github.com/shirou/gopsutil/common"
|
||||||
|
cpu "github.com/shirou/gopsutil/cpu"
|
||||||
|
net "github.com/shirou/gopsutil/net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MemoryInfoExStat is different between OSes
|
||||||
|
type MemoryInfoExStat struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type MemoryMapsStat struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func Pids() ([]int32, error) {
|
||||||
|
var ret []int32
|
||||||
|
procs, err := processes()
|
||||||
|
if err != nil {
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range procs {
|
||||||
|
ret = append(ret, p.Pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Ppid() (int32, error) {
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return k.KiPpid, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Name() (string, error) {
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(k.KiComm[:]), nil
|
||||||
|
}
|
||||||
|
func (p *Process) Exe() (string, error) {
|
||||||
|
return "", common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Cmdline() (string, error) {
|
||||||
|
return "", common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) CreateTime() (int64, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Cwd() (string, error) {
|
||||||
|
return "", common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Parent() (*Process, error) {
|
||||||
|
return p, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Status() (string, error) {
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(k.KiStat[:]), nil
|
||||||
|
}
|
||||||
|
func (p *Process) Uids() ([]int32, error) {
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
uids := make([]int32, 0, 3)
|
||||||
|
|
||||||
|
uids = append(uids, int32(k.KiRuid), int32(k.KiUID), int32(k.KiSvuid))
|
||||||
|
|
||||||
|
return uids, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Gids() ([]int32, error) {
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
gids := make([]int32, 0, 3)
|
||||||
|
gids = append(gids, int32(k.KiRgid), int32(k.KiNgroups[0]), int32(k.KiSvuid))
|
||||||
|
|
||||||
|
return gids, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Terminal() (string, error) {
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
ttyNr := uint64(k.KiTdev)
|
||||||
|
|
||||||
|
termmap, err := getTerminalMap()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return termmap[ttyNr], nil
|
||||||
|
}
|
||||||
|
func (p *Process) Nice() (int32, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) IOnice() (int32, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Rlimit() ([]RlimitStat, error) {
|
||||||
|
var rlimit []RlimitStat
|
||||||
|
return rlimit, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) IOCounters() (*IOCountersStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) NumFDs() (int32, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) NumThreads() (int32, error) {
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return k.KiNumthreads, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Threads() (map[string]string, error) {
|
||||||
|
ret := make(map[string]string, 0)
|
||||||
|
return ret, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) CPUAffinity() ([]int32, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
|
||||||
|
k, err := p.getKProc()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := &MemoryInfoStat{
|
||||||
|
RSS: uint64(k.KiRssize),
|
||||||
|
VMS: uint64(k.KiSize),
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryPercent() (float32, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Children() ([]*Process, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Connections() ([]net.NetConnectionStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) IsRunning() (bool, error) {
|
||||||
|
return true, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
|
||||||
|
var ret []MemoryMapsStat
|
||||||
|
return &ret, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyParams(k *KinfoProc, p *Process) error {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func processes() ([]Process, error) {
|
||||||
|
results := make([]Process, 0, 50)
|
||||||
|
|
||||||
|
mib := []int32{CTLKern, KernProc, KernProcProc, 0}
|
||||||
|
buf, length, err := common.CallSyscall(mib)
|
||||||
|
if err != nil {
|
||||||
|
return results, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// get kinfo_proc size
|
||||||
|
k := KinfoProc{}
|
||||||
|
procinfoLen := int(unsafe.Sizeof(k))
|
||||||
|
count := int(length / uint64(procinfoLen))
|
||||||
|
|
||||||
|
// parse buf to procs
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
b := buf[i*procinfoLen : i*procinfoLen+procinfoLen]
|
||||||
|
k, err := parseKinfoProc(b)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p, err := NewProcess(int32(k.KiPid))
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
copyParams(&k, p)
|
||||||
|
|
||||||
|
results = append(results, *p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseKinfoProc(buf []byte) (KinfoProc, error) {
|
||||||
|
var k KinfoProc
|
||||||
|
br := bytes.NewReader(buf)
|
||||||
|
err := binary.Read(br, binary.LittleEndian, &k)
|
||||||
|
if err != nil {
|
||||||
|
return k, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return k, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) getKProc() (*KinfoProc, error) {
|
||||||
|
mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid}
|
||||||
|
|
||||||
|
buf, length, err := common.CallSyscall(mib)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
procK := KinfoProc{}
|
||||||
|
if length != uint64(unsafe.Sizeof(procK)) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
k, err := parseKinfoProc(buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &k, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProcess(pid int32) (*Process, error) {
|
||||||
|
p := &Process{Pid: pid}
|
||||||
|
|
||||||
|
return p, nil
|
||||||
|
}
|
96
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd_386.go
generated
vendored
Normal file
96
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd_386.go
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
// +build freebsd
|
||||||
|
// +build 386
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
// copied from sys/sysctl.h
|
||||||
|
const (
|
||||||
|
CTLKern = 1 // "high kernel": proc, limits
|
||||||
|
KernProc = 14 // struct: process entries
|
||||||
|
KernProcPID = 1 // by process id
|
||||||
|
KernProcProc = 8 // only return procs
|
||||||
|
KernProcPathname = 12 // path to executable
|
||||||
|
)
|
||||||
|
|
||||||
|
// copied from sys/user.h
|
||||||
|
type KinfoProc struct {
|
||||||
|
KiStructsize int32
|
||||||
|
KiLayout int32
|
||||||
|
KiArgs int32
|
||||||
|
KiPaddr int32
|
||||||
|
KiAddr int32
|
||||||
|
KiTracep int32
|
||||||
|
KiTextvp int32
|
||||||
|
KiFd int32
|
||||||
|
KiVmspace int32
|
||||||
|
KiWchan int32
|
||||||
|
KiPid int32
|
||||||
|
KiPpid int32
|
||||||
|
KiPgid int32
|
||||||
|
KiTpgid int32
|
||||||
|
KiSid int32
|
||||||
|
KiTsid int32
|
||||||
|
KiJobc [2]byte
|
||||||
|
KiSpareShort1 [2]byte
|
||||||
|
KiTdev int32
|
||||||
|
KiSiglist [16]byte
|
||||||
|
KiSigmask [16]byte
|
||||||
|
KiSigignore [16]byte
|
||||||
|
KiSigcatch [16]byte
|
||||||
|
KiUID int32
|
||||||
|
KiRuid int32
|
||||||
|
KiSvuid int32
|
||||||
|
KiRgid int32
|
||||||
|
KiSvgid int32
|
||||||
|
KiNgroups [2]byte
|
||||||
|
KiSpareShort2 [2]byte
|
||||||
|
KiGroups [64]byte
|
||||||
|
KiSize int32
|
||||||
|
KiRssize int32
|
||||||
|
KiSwrss int32
|
||||||
|
KiTsize int32
|
||||||
|
KiDsize int32
|
||||||
|
KiSsize int32
|
||||||
|
KiXstat [2]byte
|
||||||
|
KiAcflag [2]byte
|
||||||
|
KiPctcpu int32
|
||||||
|
KiEstcpu int32
|
||||||
|
KiSlptime int32
|
||||||
|
KiSwtime int32
|
||||||
|
KiCow int32
|
||||||
|
KiRuntime int64
|
||||||
|
KiStart [8]byte
|
||||||
|
KiChildtime [8]byte
|
||||||
|
KiFlag int32
|
||||||
|
KiKflag int32
|
||||||
|
KiTraceflag int32
|
||||||
|
KiStat [1]byte
|
||||||
|
KiNice [1]byte
|
||||||
|
KiLock [1]byte
|
||||||
|
KiRqindex [1]byte
|
||||||
|
KiOncpu [1]byte
|
||||||
|
KiLastcpu [1]byte
|
||||||
|
KiOcomm [17]byte
|
||||||
|
KiWmesg [9]byte
|
||||||
|
KiLogin [18]byte
|
||||||
|
KiLockname [9]byte
|
||||||
|
KiComm [20]byte
|
||||||
|
KiEmul [17]byte
|
||||||
|
KiSparestrings [68]byte
|
||||||
|
KiSpareints [36]byte
|
||||||
|
KiCrFlags int32
|
||||||
|
KiJid int32
|
||||||
|
KiNumthreads int32
|
||||||
|
KiTid int32
|
||||||
|
KiPri int32
|
||||||
|
KiRusage [72]byte
|
||||||
|
KiRusageCh [72]byte
|
||||||
|
KiPcb int32
|
||||||
|
KiKstack int32
|
||||||
|
KiUdata int32
|
||||||
|
KiTdaddr int32
|
||||||
|
KiSpareptrs [24]byte
|
||||||
|
KiSpareint64s [48]byte
|
||||||
|
KiSflag int32
|
||||||
|
KiTdflags int32
|
||||||
|
}
|
96
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd_amd64.go
generated
vendored
Normal file
96
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_freebsd_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
// +build freebsd
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
// copied from sys/sysctl.h
|
||||||
|
const (
|
||||||
|
CTLKern = 1 // "high kernel": proc, limits
|
||||||
|
KernProc = 14 // struct: process entries
|
||||||
|
KernProcPID = 1 // by process id
|
||||||
|
KernProcProc = 8 // only return procs
|
||||||
|
KernProcPathname = 12 // path to executable
|
||||||
|
)
|
||||||
|
|
||||||
|
// copied from sys/user.h
|
||||||
|
type KinfoProc struct {
|
||||||
|
KiStructsize int32
|
||||||
|
KiLayout int32
|
||||||
|
KiArgs int64
|
||||||
|
KiPaddr int64
|
||||||
|
KiAddr int64
|
||||||
|
KiTracep int64
|
||||||
|
KiTextvp int64
|
||||||
|
KiFd int64
|
||||||
|
KiVmspace int64
|
||||||
|
KiWchan int64
|
||||||
|
KiPid int32
|
||||||
|
KiPpid int32
|
||||||
|
KiPgid int32
|
||||||
|
KiTpgid int32
|
||||||
|
KiSid int32
|
||||||
|
KiTsid int32
|
||||||
|
KiJobc [2]byte
|
||||||
|
KiSpareShort1 [2]byte
|
||||||
|
KiTdev int32
|
||||||
|
KiSiglist [16]byte
|
||||||
|
KiSigmask [16]byte
|
||||||
|
KiSigignore [16]byte
|
||||||
|
KiSigcatch [16]byte
|
||||||
|
KiUID int32
|
||||||
|
KiRuid int32
|
||||||
|
KiSvuid int32
|
||||||
|
KiRgid int32
|
||||||
|
KiSvgid int32
|
||||||
|
KiNgroups [2]byte
|
||||||
|
KiSpareShort2 [2]byte
|
||||||
|
KiGroups [64]byte
|
||||||
|
KiSize int64
|
||||||
|
KiRssize int64
|
||||||
|
KiSwrss int64
|
||||||
|
KiTsize int64
|
||||||
|
KiDsize int64
|
||||||
|
KiSsize int64
|
||||||
|
KiXstat [2]byte
|
||||||
|
KiAcflag [2]byte
|
||||||
|
KiPctcpu int32
|
||||||
|
KiEstcpu int32
|
||||||
|
KiSlptime int32
|
||||||
|
KiSwtime int32
|
||||||
|
KiCow int32
|
||||||
|
KiRuntime int64
|
||||||
|
KiStart [16]byte
|
||||||
|
KiChildtime [16]byte
|
||||||
|
KiFlag int64
|
||||||
|
KiKflag int64
|
||||||
|
KiTraceflag int32
|
||||||
|
KiStat [1]byte
|
||||||
|
KiNice [1]byte
|
||||||
|
KiLock [1]byte
|
||||||
|
KiRqindex [1]byte
|
||||||
|
KiOncpu [1]byte
|
||||||
|
KiLastcpu [1]byte
|
||||||
|
KiOcomm [17]byte
|
||||||
|
KiWmesg [9]byte
|
||||||
|
KiLogin [18]byte
|
||||||
|
KiLockname [9]byte
|
||||||
|
KiComm [20]byte
|
||||||
|
KiEmul [17]byte
|
||||||
|
KiSparestrings [68]byte
|
||||||
|
KiSpareints [36]byte
|
||||||
|
KiCrFlags int32
|
||||||
|
KiJid int32
|
||||||
|
KiNumthreads int32
|
||||||
|
KiTid int32
|
||||||
|
KiPri int32
|
||||||
|
KiRusage [144]byte
|
||||||
|
KiRusageCh [144]byte
|
||||||
|
KiPcb int64
|
||||||
|
KiKstack int64
|
||||||
|
KiUdata int64
|
||||||
|
KiTdaddr int64
|
||||||
|
KiSpareptrs [48]byte
|
||||||
|
KiSpareint64s [96]byte
|
||||||
|
KiSflag int64
|
||||||
|
KiTdflags int64
|
||||||
|
}
|
656
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_linux.go
generated
vendored
Normal file
656
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,656 @@
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/common"
|
||||||
|
"github.com/shirou/gopsutil/cpu"
|
||||||
|
"github.com/shirou/gopsutil/host"
|
||||||
|
"github.com/shirou/gopsutil/net"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PrioProcess = 0 // linux/resource.h
|
||||||
|
)
|
||||||
|
|
||||||
|
// MemoryInfoExStat is different between OSes
|
||||||
|
type MemoryInfoExStat struct {
|
||||||
|
RSS uint64 `json:"rss"` // bytes
|
||||||
|
VMS uint64 `json:"vms"` // bytes
|
||||||
|
Shared uint64 `json:"shared"` // bytes
|
||||||
|
Text uint64 `json:"text"` // bytes
|
||||||
|
Lib uint64 `json:"lib"` // bytes
|
||||||
|
Data uint64 `json:"data"` // bytes
|
||||||
|
Dirty uint64 `json:"dirty"` // bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MemoryInfoExStat) String() string {
|
||||||
|
s, _ := json.Marshal(m)
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MemoryMapsStat struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
Rss uint64 `json:"rss"`
|
||||||
|
Size uint64 `json:"size"`
|
||||||
|
Pss uint64 `json:"pss"`
|
||||||
|
SharedClean uint64 `json:"shared_clean"`
|
||||||
|
SharedDirty uint64 `json:"shared_dirty"`
|
||||||
|
PrivateClean uint64 `json:"private_clean"`
|
||||||
|
PrivateDirty uint64 `json:"private_dirty"`
|
||||||
|
Referenced uint64 `json:"referenced"`
|
||||||
|
Anonymous uint64 `json:"anonymous"`
|
||||||
|
Swap uint64 `json:"swap"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MemoryMapsStat) String() string {
|
||||||
|
s, _ := json.Marshal(m)
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new Process instance
|
||||||
|
// This only stores Pid
|
||||||
|
func NewProcess(pid int32) (*Process, error) {
|
||||||
|
p := &Process{
|
||||||
|
Pid: int32(pid),
|
||||||
|
}
|
||||||
|
err := p.fillFromStatus()
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Ppid() (int32, error) {
|
||||||
|
_, ppid, _, _, _, err := p.fillFromStat()
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
return ppid, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Name() (string, error) {
|
||||||
|
return p.name, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Exe() (string, error) {
|
||||||
|
return p.fillFromExe()
|
||||||
|
}
|
||||||
|
func (p *Process) Cmdline() (string, error) {
|
||||||
|
return p.fillFromCmdline()
|
||||||
|
}
|
||||||
|
func (p *Process) CreateTime() (int64, error) {
|
||||||
|
_, _, _, createTime, _, err := p.fillFromStat()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return createTime, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Cwd() (string, error) {
|
||||||
|
return p.fillFromCwd()
|
||||||
|
}
|
||||||
|
func (p *Process) Parent() (*Process, error) {
|
||||||
|
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) {
|
||||||
|
err := p.fillFromStatus()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return p.status, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Uids() ([]int32, error) {
|
||||||
|
err := p.fillFromStatus()
|
||||||
|
if err != nil {
|
||||||
|
return []int32{}, err
|
||||||
|
}
|
||||||
|
return p.uids, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Gids() ([]int32, error) {
|
||||||
|
err := p.fillFromStatus()
|
||||||
|
if err != nil {
|
||||||
|
return []int32{}, err
|
||||||
|
}
|
||||||
|
return p.gids, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Terminal() (string, error) {
|
||||||
|
terminal, _, _, _, _, err := p.fillFromStat()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return terminal, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Nice() (int32, error) {
|
||||||
|
_, _, _, _, nice, err := p.fillFromStat()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return nice, nil
|
||||||
|
}
|
||||||
|
func (p *Process) IOnice() (int32, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Rlimit() ([]RlimitStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) IOCounters() (*IOCountersStat, error) {
|
||||||
|
return p.fillFromIO()
|
||||||
|
}
|
||||||
|
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
|
||||||
|
err := p.fillFromStatus()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return p.numCtxSwitches, nil
|
||||||
|
}
|
||||||
|
func (p *Process) NumFDs() (int32, error) {
|
||||||
|
numFds, _, err := p.fillFromfd()
|
||||||
|
return numFds, err
|
||||||
|
}
|
||||||
|
func (p *Process) NumThreads() (int32, error) {
|
||||||
|
err := p.fillFromStatus()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return p.numThreads, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Threads() (map[string]string, error) {
|
||||||
|
ret := make(map[string]string, 0)
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) {
|
||||||
|
_, _, cpuTimes, _, _, err := p.fillFromStat()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return cpuTimes, nil
|
||||||
|
}
|
||||||
|
func (p *Process) CPUAffinity() ([]int32, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
|
||||||
|
_, _, err := p.fillFromStatm()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return p.memInfo, nil
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
|
||||||
|
_, memInfoEx, err := p.fillFromStatm()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return memInfoEx, nil
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryPercent() (float32, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Children() ([]*Process, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Connections() ([]net.NetConnectionStat, error) {
|
||||||
|
return net.NetConnectionsPid("all", p.Pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) IsRunning() (bool, error) {
|
||||||
|
return true, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
// MemoryMaps get memory maps from /proc/(pid)/smaps
|
||||||
|
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
|
||||||
|
pid := p.Pid
|
||||||
|
var ret []MemoryMapsStat
|
||||||
|
smapsPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "smaps")
|
||||||
|
contents, err := ioutil.ReadFile(smapsPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
lines := strings.Split(string(contents), "\n")
|
||||||
|
|
||||||
|
// function of parsing a block
|
||||||
|
getBlock := func(first_line []string, block []string) (MemoryMapsStat, error) {
|
||||||
|
m := MemoryMapsStat{}
|
||||||
|
m.Path = first_line[len(first_line)-1]
|
||||||
|
|
||||||
|
for _, line := range block {
|
||||||
|
if strings.Contains(line, "VmFlags") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
field := strings.Split(line, ":")
|
||||||
|
if len(field) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v := strings.Trim(field[1], " kB") // remove last "kB"
|
||||||
|
t, err := strconv.ParseUint(v, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return m, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch field[0] {
|
||||||
|
case "Size":
|
||||||
|
m.Size = t
|
||||||
|
case "Rss":
|
||||||
|
m.Rss = t
|
||||||
|
case "Pss":
|
||||||
|
m.Pss = t
|
||||||
|
case "Shared_Clean":
|
||||||
|
m.SharedClean = t
|
||||||
|
case "Shared_Dirty":
|
||||||
|
m.SharedDirty = t
|
||||||
|
case "Private_Clean":
|
||||||
|
m.PrivateClean = t
|
||||||
|
case "Private_Dirty":
|
||||||
|
m.PrivateDirty = t
|
||||||
|
case "Referenced":
|
||||||
|
m.Referenced = t
|
||||||
|
case "Anonymous":
|
||||||
|
m.Anonymous = t
|
||||||
|
case "Swap":
|
||||||
|
m.Swap = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks := make([]string, 16)
|
||||||
|
for _, line := range lines {
|
||||||
|
field := strings.Split(line, " ")
|
||||||
|
if strings.HasSuffix(field[0], ":") == false {
|
||||||
|
// new block section
|
||||||
|
if len(blocks) > 0 {
|
||||||
|
g, err := getBlock(field, blocks)
|
||||||
|
if err != nil {
|
||||||
|
return &ret, err
|
||||||
|
}
|
||||||
|
ret = append(ret, g)
|
||||||
|
}
|
||||||
|
// starts new block
|
||||||
|
blocks = make([]string, 16)
|
||||||
|
} else {
|
||||||
|
blocks = append(blocks, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Internal functions
|
||||||
|
**/
|
||||||
|
|
||||||
|
// Get num_fds from /proc/(pid)/fd
|
||||||
|
func (p *Process) fillFromfd() (int32, []*OpenFilesStat, error) {
|
||||||
|
pid := p.Pid
|
||||||
|
statPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "fd")
|
||||||
|
d, err := os.Open(statPath)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
defer d.Close()
|
||||||
|
fnames, err := d.Readdirnames(-1)
|
||||||
|
numFDs := int32(len(fnames))
|
||||||
|
|
||||||
|
openfiles := make([]*OpenFilesStat, numFDs)
|
||||||
|
for _, fd := range fnames {
|
||||||
|
fpath := filepath.Join(statPath, fd)
|
||||||
|
filepath, err := os.Readlink(fpath)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
t, err := strconv.ParseUint(fd, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return numFDs, openfiles, err
|
||||||
|
}
|
||||||
|
o := &OpenFilesStat{
|
||||||
|
Path: filepath,
|
||||||
|
Fd: t,
|
||||||
|
}
|
||||||
|
openfiles = append(openfiles, o)
|
||||||
|
}
|
||||||
|
|
||||||
|
return numFDs, openfiles, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get cwd from /proc/(pid)/cwd
|
||||||
|
func (p *Process) fillFromCwd() (string, error) {
|
||||||
|
pid := p.Pid
|
||||||
|
cwdPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "cwd")
|
||||||
|
cwd, err := os.Readlink(cwdPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(cwd), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get exe from /proc/(pid)/exe
|
||||||
|
func (p *Process) fillFromExe() (string, error) {
|
||||||
|
pid := p.Pid
|
||||||
|
exePath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "exe")
|
||||||
|
exe, err := os.Readlink(exePath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(exe), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get cmdline from /proc/(pid)/cmdline
|
||||||
|
func (p *Process) fillFromCmdline() (string, error) {
|
||||||
|
pid := p.Pid
|
||||||
|
cmdPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "cmdline")
|
||||||
|
cmdline, err := ioutil.ReadFile(cmdPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
ret := strings.FieldsFunc(string(cmdline), func(r rune) bool {
|
||||||
|
if r == '\u0000' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
return strings.Join(ret, " "), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get IO status from /proc/(pid)/io
|
||||||
|
func (p *Process) fillFromIO() (*IOCountersStat, error) {
|
||||||
|
pid := p.Pid
|
||||||
|
ioPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "io")
|
||||||
|
ioline, err := ioutil.ReadFile(ioPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
lines := strings.Split(string(ioline), "\n")
|
||||||
|
ret := &IOCountersStat{}
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
field := strings.Fields(line)
|
||||||
|
if len(field) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
t, err := strconv.ParseUint(field[1], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
param := field[0]
|
||||||
|
if strings.HasSuffix(param, ":") {
|
||||||
|
param = param[:len(param)-1]
|
||||||
|
}
|
||||||
|
switch param {
|
||||||
|
case "syscr":
|
||||||
|
ret.ReadCount = t
|
||||||
|
case "syscw":
|
||||||
|
ret.WriteCount = t
|
||||||
|
case "read_bytes":
|
||||||
|
ret.ReadBytes = t
|
||||||
|
case "write_bytes":
|
||||||
|
ret.WriteBytes = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get memory info from /proc/(pid)/statm
|
||||||
|
func (p *Process) fillFromStatm() (*MemoryInfoStat, *MemoryInfoExStat, error) {
|
||||||
|
pid := p.Pid
|
||||||
|
memPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "statm")
|
||||||
|
contents, err := ioutil.ReadFile(memPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
fields := strings.Split(string(contents), " ")
|
||||||
|
|
||||||
|
vms, err := strconv.ParseUint(fields[0], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
rss, err := strconv.ParseUint(fields[1], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
memInfo := &MemoryInfoStat{
|
||||||
|
RSS: rss * PageSize,
|
||||||
|
VMS: vms * PageSize,
|
||||||
|
}
|
||||||
|
|
||||||
|
shared, err := strconv.ParseUint(fields[2], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
text, err := strconv.ParseUint(fields[3], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
lib, err := strconv.ParseUint(fields[4], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
dirty, err := strconv.ParseUint(fields[5], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
memInfoEx := &MemoryInfoExStat{
|
||||||
|
RSS: rss * PageSize,
|
||||||
|
VMS: vms * PageSize,
|
||||||
|
Shared: shared * PageSize,
|
||||||
|
Text: text * PageSize,
|
||||||
|
Lib: lib * PageSize,
|
||||||
|
Dirty: dirty * PageSize,
|
||||||
|
}
|
||||||
|
|
||||||
|
return memInfo, memInfoEx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get various status from /proc/(pid)/status
|
||||||
|
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 err
|
||||||
|
}
|
||||||
|
lines := strings.Split(string(contents), "\n")
|
||||||
|
p.numCtxSwitches = &NumCtxSwitchesStat{}
|
||||||
|
p.memInfo = &MemoryInfoStat{}
|
||||||
|
for _, line := range lines {
|
||||||
|
tabParts := strings.SplitN(line, "\t", 2)
|
||||||
|
if len(tabParts) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
value := tabParts[1]
|
||||||
|
switch strings.TrimRight(tabParts[0], ":") {
|
||||||
|
case "Name":
|
||||||
|
p.name = strings.Trim(value, " \t")
|
||||||
|
case "State":
|
||||||
|
// get between "(" and ")"
|
||||||
|
s := strings.Index(value, "(") + 1
|
||||||
|
e := strings.Index(value, ")")
|
||||||
|
p.status = value[s:e]
|
||||||
|
case "Uid":
|
||||||
|
p.uids = make([]int32, 0, 4)
|
||||||
|
for _, i := range strings.Split(value, "\t") {
|
||||||
|
v, err := strconv.ParseInt(i, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.uids = append(p.uids, int32(v))
|
||||||
|
}
|
||||||
|
case "Gid":
|
||||||
|
p.gids = make([]int32, 0, 4)
|
||||||
|
for _, i := range strings.Split(value, "\t") {
|
||||||
|
v, err := strconv.ParseInt(i, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.gids = append(p.gids, int32(v))
|
||||||
|
}
|
||||||
|
case "Threads":
|
||||||
|
v, err := strconv.ParseInt(value, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.numThreads = int32(v)
|
||||||
|
case "voluntary_ctxt_switches":
|
||||||
|
v, err := strconv.ParseInt(value, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.numCtxSwitches.Voluntary = v
|
||||||
|
case "nonvoluntary_ctxt_switches":
|
||||||
|
v, err := strconv.ParseInt(value, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.numCtxSwitches.Involuntary = v
|
||||||
|
case "VmRSS":
|
||||||
|
value := strings.Trim(value, " kB") // remove last "kB"
|
||||||
|
v, err := strconv.ParseUint(value, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.memInfo.RSS = v * 1024
|
||||||
|
case "VmSize":
|
||||||
|
value := strings.Trim(value, " kB") // remove last "kB"
|
||||||
|
v, err := strconv.ParseUint(value, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.memInfo.VMS = v * 1024
|
||||||
|
case "VmSwap":
|
||||||
|
value := strings.Trim(value, " kB") // remove last "kB"
|
||||||
|
v, err := strconv.ParseUint(value, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.memInfo.Swap = v * 1024
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) fillFromStat() (string, int32, *cpu.CPUTimesStat, int64, int32, error) {
|
||||||
|
pid := p.Pid
|
||||||
|
statPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "stat")
|
||||||
|
contents, err := ioutil.ReadFile(statPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, nil, 0, 0, err
|
||||||
|
}
|
||||||
|
fields := strings.Fields(string(contents))
|
||||||
|
|
||||||
|
termmap, err := getTerminalMap()
|
||||||
|
terminal := ""
|
||||||
|
if err == nil {
|
||||||
|
t, err := strconv.ParseUint(fields[6], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, nil, 0, 0, err
|
||||||
|
}
|
||||||
|
terminal = termmap[t]
|
||||||
|
}
|
||||||
|
|
||||||
|
ppid, err := strconv.ParseInt(fields[3], 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, nil, 0, 0, err
|
||||||
|
}
|
||||||
|
utime, err := strconv.ParseFloat(fields[13], 64)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, nil, 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stime, err := strconv.ParseFloat(fields[14], 64)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, nil, 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cpuTimes := &cpu.CPUTimesStat{
|
||||||
|
CPU: "cpu",
|
||||||
|
User: float64(utime / ClockTicks),
|
||||||
|
System: float64(stime / ClockTicks),
|
||||||
|
}
|
||||||
|
|
||||||
|
bootTime, _ := host.BootTime()
|
||||||
|
t, err := strconv.ParseUint(fields[21], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, nil, 0, 0, err
|
||||||
|
}
|
||||||
|
ctime := (t / uint64(ClockTicks)) + uint64(bootTime)*1000
|
||||||
|
createTime := int64(ctime)
|
||||||
|
|
||||||
|
// p.Nice = mustParseInt32(fields[18])
|
||||||
|
// use syscall instead of parse Stat file
|
||||||
|
snice, _ := syscall.Getpriority(PrioProcess, int(pid))
|
||||||
|
nice := int32(snice) // FIXME: is this true?
|
||||||
|
|
||||||
|
return terminal, int32(ppid), cpuTimes, createTime, nice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Pids() ([]int32, error) {
|
||||||
|
var ret []int32
|
||||||
|
|
||||||
|
d, err := os.Open("/proc")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer d.Close()
|
||||||
|
|
||||||
|
fnames, err := d.Readdirnames(-1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, fname := range fnames {
|
||||||
|
pid, err := strconv.ParseInt(fname, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
// if not numeric name, just skip
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ret = append(ret, int32(pid))
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
9
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_linux_386.go
generated
vendored
Normal file
9
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_linux_386.go
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// +build linux
|
||||||
|
// +build 386
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
const (
|
||||||
|
ClockTicks = 100 // C.sysconf(C._SC_CLK_TCK)
|
||||||
|
PageSize = 4096 // C.sysconf(C._SC_PAGE_SIZE)
|
||||||
|
)
|
9
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_linux_amd64.go
generated
vendored
Normal file
9
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_linux_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// +build linux
|
||||||
|
// +build amd64
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
const (
|
||||||
|
ClockTicks = 100 // C.sysconf(C._SC_CLK_TCK)
|
||||||
|
PageSize = 4096 // C.sysconf(C._SC_PAGE_SIZE)
|
||||||
|
)
|
9
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_linux_arm.go
generated
vendored
Normal file
9
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_linux_arm.go
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// +build linux
|
||||||
|
// +build arm
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
const (
|
||||||
|
ClockTicks = 100 // C.sysconf(C._SC_CLK_TCK)
|
||||||
|
PageSize = 4096 // C.sysconf(C._SC_PAGE_SIZE)
|
||||||
|
)
|
102
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_posix.go
generated
vendored
Normal file
102
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_posix.go
generated
vendored
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
// +build linux freebsd darwin
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"os/user"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// POSIX
|
||||||
|
func getTerminalMap() (map[uint64]string, error) {
|
||||||
|
ret := make(map[uint64]string)
|
||||||
|
var termfiles []string
|
||||||
|
|
||||||
|
d, err := os.Open("/dev")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer d.Close()
|
||||||
|
|
||||||
|
devnames, err := d.Readdirnames(-1)
|
||||||
|
for _, devname := range devnames {
|
||||||
|
if strings.HasPrefix(devname, "/dev/tty") {
|
||||||
|
termfiles = append(termfiles, "/dev/tty/"+devname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ptsd, err := os.Open("/dev/pts")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer ptsd.Close()
|
||||||
|
|
||||||
|
ptsnames, err := ptsd.Readdirnames(-1)
|
||||||
|
for _, ptsname := range ptsnames {
|
||||||
|
termfiles = append(termfiles, "/dev/pts/"+ptsname)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range termfiles {
|
||||||
|
stat := syscall.Stat_t{}
|
||||||
|
if err = syscall.Stat(name, &stat); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rdev := uint64(stat.Rdev)
|
||||||
|
ret[rdev] = strings.Replace(name, "/dev", "", -1)
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) SendSignal(sig syscall.Signal) error {
|
||||||
|
sigAsStr := "INT"
|
||||||
|
switch sig {
|
||||||
|
case syscall.SIGSTOP:
|
||||||
|
sigAsStr = "STOP"
|
||||||
|
case syscall.SIGCONT:
|
||||||
|
sigAsStr = "CONT"
|
||||||
|
case syscall.SIGTERM:
|
||||||
|
sigAsStr = "TERM"
|
||||||
|
case syscall.SIGKILL:
|
||||||
|
sigAsStr = "KILL"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("kill", "-s", sigAsStr, strconv.Itoa(int(p.Pid)))
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Suspend() error {
|
||||||
|
return p.SendSignal(syscall.SIGSTOP)
|
||||||
|
}
|
||||||
|
func (p *Process) Resume() error {
|
||||||
|
return p.SendSignal(syscall.SIGCONT)
|
||||||
|
}
|
||||||
|
func (p *Process) Terminate() error {
|
||||||
|
return p.SendSignal(syscall.SIGTERM)
|
||||||
|
}
|
||||||
|
func (p *Process) Kill() error {
|
||||||
|
return p.SendSignal(syscall.SIGKILL)
|
||||||
|
}
|
||||||
|
func (p *Process) Username() (string, error) {
|
||||||
|
uids, err := p.Uids()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if len(uids) > 0 {
|
||||||
|
u, err := user.LookupId(strconv.Itoa(int(uids[0])))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return u.Username, nil
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
}
|
19
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_posix_test.go
generated
vendored
Normal file
19
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_posix_test.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// +build linux freebsd
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_SendSignal(t *testing.T) {
|
||||||
|
checkPid := os.Getpid()
|
||||||
|
|
||||||
|
p, _ := NewProcess(int32(checkPid))
|
||||||
|
err := p.SendSignal(syscall.SIGCONT)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("send signal %v", err)
|
||||||
|
}
|
||||||
|
}
|
306
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_test.go
generated
vendored
Normal file
306
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_test.go
generated
vendored
Normal file
|
@ -0,0 +1,306 @@
|
||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
var mu sync.Mutex
|
||||||
|
|
||||||
|
func testGetProcess() Process {
|
||||||
|
checkPid := os.Getpid() // process.test
|
||||||
|
ret, _ := NewProcess(int32(checkPid))
|
||||||
|
return *ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Pids(t *testing.T) {
|
||||||
|
ret, err := Pids()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
if len(ret) == 0 {
|
||||||
|
t.Errorf("could not get pids %v", ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Pids_Fail(t *testing.T) {
|
||||||
|
if runtime.GOOS != "darwin" {
|
||||||
|
t.Skip("darwin only")
|
||||||
|
}
|
||||||
|
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
|
||||||
|
invoke = common.FakeInvoke{Suffix: "fail"}
|
||||||
|
ret, err := Pids()
|
||||||
|
invoke = common.Invoke{}
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
if len(ret) != 9 {
|
||||||
|
t.Errorf("wrong getted pid nums: %v/%d", ret, len(ret))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func Test_Pid_exists(t *testing.T) {
|
||||||
|
checkPid := os.Getpid()
|
||||||
|
|
||||||
|
ret, err := PidExists(int32(checkPid))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ret == false {
|
||||||
|
t.Errorf("could not get process exists: %v", ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_NewProcess(t *testing.T) {
|
||||||
|
checkPid := os.Getpid()
|
||||||
|
|
||||||
|
ret, err := NewProcess(int32(checkPid))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
empty := &Process{}
|
||||||
|
if runtime.GOOS != "windows" { // Windows pid is 0
|
||||||
|
if empty == ret {
|
||||||
|
t.Errorf("error %v", ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Process_memory_maps(t *testing.T) {
|
||||||
|
checkPid := os.Getpid()
|
||||||
|
|
||||||
|
ret, err := NewProcess(int32(checkPid))
|
||||||
|
|
||||||
|
mmaps, err := ret.MemoryMaps(false)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("memory map get error %v", err)
|
||||||
|
}
|
||||||
|
empty := MemoryMapsStat{}
|
||||||
|
for _, m := range *mmaps {
|
||||||
|
if m == empty {
|
||||||
|
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 memory info error %v", err)
|
||||||
|
}
|
||||||
|
empty := MemoryInfoStat{}
|
||||||
|
if v == nil || *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 cmdline error %v", err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(v, "process.test") {
|
||||||
|
t.Errorf("invalid cmd line %v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Process_Ppid(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
|
||||||
|
v, err := p.Ppid()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("geting ppid error %v", err)
|
||||||
|
}
|
||||||
|
if v == 0 {
|
||||||
|
t.Errorf("return value is 0 %v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Process_Status(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
|
||||||
|
v, err := p.Status()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("geting status error %v", err)
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(v, "S") && v != "running" && v != "sleeping" {
|
||||||
|
t.Errorf("could not get state %v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Process_Terminal(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
|
||||||
|
_, err := p.Terminal()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("geting terminal error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if v == "" {
|
||||||
|
t.Errorf("could not get terminal %v", v)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Process_IOCounters(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
|
||||||
|
v, err := p.IOCounters()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("geting iocounter error %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
empty := &IOCountersStat{}
|
||||||
|
if v == empty {
|
||||||
|
t.Errorf("error %v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Process_NumCtx(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
|
||||||
|
_, err := p.NumCtxSwitches()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("geting numctx error %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Process_Nice(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
|
||||||
|
n, err := p.Nice()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("geting nice error %v", err)
|
||||||
|
}
|
||||||
|
if n != 0 && n != 20 && n != 8 {
|
||||||
|
t.Errorf("invalid nice: %d", n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func Test_Process_NumThread(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
|
||||||
|
n, err := p.NumThreads()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("geting NumThread error %v", err)
|
||||||
|
}
|
||||||
|
if n < 0 {
|
||||||
|
t.Errorf("invalid NumThread: %d", n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Process_Name(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
|
||||||
|
n, err := p.Name()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("geting name error %v", err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(n, "process.test") {
|
||||||
|
t.Errorf("invalid Exe %s", n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func Test_Process_Exe(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
|
||||||
|
n, err := p.Exe()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("geting Exe error %v", err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(n, "process.test") {
|
||||||
|
t.Errorf("invalid Exe %s", n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Process_CpuPercent(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
percent, err := p.CPUPercent(0)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
duration := time.Duration(1000) * time.Microsecond
|
||||||
|
time.Sleep(duration)
|
||||||
|
percent, err = p.CPUPercent(0)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
numcpu := runtime.NumCPU()
|
||||||
|
// if percent < 0.0 || percent > 100.0*float64(numcpu) { // TODO
|
||||||
|
if percent < 0.0 {
|
||||||
|
t.Fatalf("CPUPercent value is invalid: %f, %d", percent, numcpu)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Process_CpuPercentLoop(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
numcpu := runtime.NumCPU()
|
||||||
|
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
duration := time.Duration(100) * time.Microsecond
|
||||||
|
percent, err := p.CPUPercent(duration)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
// if percent < 0.0 || percent > 100.0*float64(numcpu) { // TODO
|
||||||
|
if percent < 0.0 {
|
||||||
|
t.Fatalf("CPUPercent value is invalid: %f, %d", percent, numcpu)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Process_CreateTime(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
|
||||||
|
c, err := p.CreateTime()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error %v", err)
|
||||||
|
}
|
||||||
|
if c < 1420000000 {
|
||||||
|
t.Errorf("process created time is wrong.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Parent(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
|
||||||
|
c, err := p.Parent()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error %v", err)
|
||||||
|
}
|
||||||
|
if c == nil {
|
||||||
|
t.Fatalf("could not get parent")
|
||||||
|
}
|
||||||
|
if c.Pid == 0 {
|
||||||
|
t.Fatalf("wrong parent pid")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Connections(t *testing.T) {
|
||||||
|
p := testGetProcess()
|
||||||
|
|
||||||
|
c, err := p.Connections()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error %v", err)
|
||||||
|
}
|
||||||
|
// TODO:
|
||||||
|
// Since go test open no conneciton, ret is empty.
|
||||||
|
// should invoke child process or other solutions.
|
||||||
|
if len(c) != 0 {
|
||||||
|
t.Fatalf("wrong connections")
|
||||||
|
}
|
||||||
|
}
|
344
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_windows.go
generated
vendored
Normal file
344
Godeps/_workspace/src/github.com/shirou/gopsutil/process/process_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,344 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/StackExchange/wmi"
|
||||||
|
"github.com/shirou/w32"
|
||||||
|
|
||||||
|
common "github.com/shirou/gopsutil/common"
|
||||||
|
cpu "github.com/shirou/gopsutil/cpu"
|
||||||
|
net "github.com/shirou/gopsutil/net"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
NoMoreFiles = 0x12
|
||||||
|
MaxPathLength = 260
|
||||||
|
)
|
||||||
|
|
||||||
|
type SystemProcessInformation struct {
|
||||||
|
NextEntryOffset uint64
|
||||||
|
NumberOfThreads uint64
|
||||||
|
Reserved1 [48]byte
|
||||||
|
Reserved2 [3]byte
|
||||||
|
UniqueProcessID uintptr
|
||||||
|
Reserved3 uintptr
|
||||||
|
HandleCount uint64
|
||||||
|
Reserved4 [4]byte
|
||||||
|
Reserved5 [11]byte
|
||||||
|
PeakPagefileUsage uint64
|
||||||
|
PrivatePageCount uint64
|
||||||
|
Reserved6 [6]uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Memory_info_ex is different between OSes
|
||||||
|
type MemoryInfoExStat struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type MemoryMapsStat struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type Win32_Process struct {
|
||||||
|
Name string
|
||||||
|
ExecutablePath *string
|
||||||
|
CommandLine *string
|
||||||
|
Priority uint32
|
||||||
|
CreationDate *time.Time
|
||||||
|
ProcessId uint32
|
||||||
|
ThreadCount uint32
|
||||||
|
|
||||||
|
/*
|
||||||
|
CSCreationClassName string
|
||||||
|
CSName string
|
||||||
|
Caption *string
|
||||||
|
CreationClassName string
|
||||||
|
Description *string
|
||||||
|
ExecutionState *uint16
|
||||||
|
HandleCount uint32
|
||||||
|
KernelModeTime uint64
|
||||||
|
MaximumWorkingSetSize *uint32
|
||||||
|
MinimumWorkingSetSize *uint32
|
||||||
|
OSCreationClassName string
|
||||||
|
OSName string
|
||||||
|
OtherOperationCount uint64
|
||||||
|
OtherTransferCount uint64
|
||||||
|
PageFaults uint32
|
||||||
|
PageFileUsage uint32
|
||||||
|
ParentProcessId uint32
|
||||||
|
PeakPageFileUsage uint32
|
||||||
|
PeakVirtualSize uint64
|
||||||
|
PeakWorkingSetSize uint32
|
||||||
|
PrivatePageCount uint64
|
||||||
|
ReadOperationCount uint64
|
||||||
|
ReadTransferCount uint64
|
||||||
|
Status *string
|
||||||
|
TerminationDate *time.Time
|
||||||
|
UserModeTime uint64
|
||||||
|
WorkingSetSize uint64
|
||||||
|
WriteOperationCount uint64
|
||||||
|
WriteTransferCount uint64
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
func Pids() ([]int32, error) {
|
||||||
|
var ret []int32
|
||||||
|
|
||||||
|
procs, err := processes()
|
||||||
|
if err != nil {
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, proc := range procs {
|
||||||
|
ret = append(ret, proc.Pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Ppid() (int32, error) {
|
||||||
|
ret, _, _, err := p.getFromSnapProcess(p.Pid)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetWin32Proc(pid int32) ([]Win32_Process, error) {
|
||||||
|
var dst []Win32_Process
|
||||||
|
query := fmt.Sprintf("WHERE ProcessId = %d", pid)
|
||||||
|
q := wmi.CreateQuery(&dst, query)
|
||||||
|
err := wmi.Query(q, &dst)
|
||||||
|
if err != nil {
|
||||||
|
return []Win32_Process{}, fmt.Errorf("could not get win32Proc: %s", err)
|
||||||
|
}
|
||||||
|
if len(dst) != 1 {
|
||||||
|
return []Win32_Process{}, fmt.Errorf("could not get win32Proc: empty")
|
||||||
|
}
|
||||||
|
return dst, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Name() (string, error) {
|
||||||
|
dst, err := GetWin32Proc(p.Pid)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("could not get Name: %s", err)
|
||||||
|
}
|
||||||
|
return dst[0].Name, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Exe() (string, error) {
|
||||||
|
dst, err := GetWin32Proc(p.Pid)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("could not get ExecutablePath: %s", err)
|
||||||
|
}
|
||||||
|
return *dst[0].ExecutablePath, nil
|
||||||
|
}
|
||||||
|
func (p *Process) Cmdline() (string, error) {
|
||||||
|
dst, err := GetWin32Proc(p.Pid)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("could not get CommandLine: %s", err)
|
||||||
|
}
|
||||||
|
return *dst[0].CommandLine, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) CreateTime() (int64, error) {
|
||||||
|
dst, err := GetWin32Proc(p.Pid)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("could not get CreationDate: %s", err)
|
||||||
|
}
|
||||||
|
date := *dst[0].CreationDate
|
||||||
|
return date.Unix(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Cwd() (string, error) {
|
||||||
|
return "", common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Parent() (*Process, error) {
|
||||||
|
return p, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Status() (string, error) {
|
||||||
|
return "", common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Username() (string, error) {
|
||||||
|
return "", common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Uids() ([]int32, error) {
|
||||||
|
var uids []int32
|
||||||
|
|
||||||
|
return uids, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Gids() ([]int32, error) {
|
||||||
|
var gids []int32
|
||||||
|
return gids, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Terminal() (string, error) {
|
||||||
|
return "", common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nice returnes priority in Windows
|
||||||
|
func (p *Process) Nice() (int32, error) {
|
||||||
|
dst, err := GetWin32Proc(p.Pid)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("could not get Priority: %s", err)
|
||||||
|
}
|
||||||
|
return int32(dst[0].Priority), nil
|
||||||
|
}
|
||||||
|
func (p *Process) IOnice() (int32, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Rlimit() ([]RlimitStat, error) {
|
||||||
|
var rlimit []RlimitStat
|
||||||
|
|
||||||
|
return rlimit, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) IOCounters() (*IOCountersStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) NumFDs() (int32, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) NumThreads() (int32, error) {
|
||||||
|
dst, err := GetWin32Proc(p.Pid)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("could not get ThreadCount: %s", err)
|
||||||
|
}
|
||||||
|
return int32(dst[0].ThreadCount), nil
|
||||||
|
}
|
||||||
|
func (p *Process) Threads() (map[string]string, error) {
|
||||||
|
ret := make(map[string]string, 0)
|
||||||
|
return ret, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) CPUAffinity() ([]int32, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) MemoryPercent() (float32, error) {
|
||||||
|
return 0, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Children() ([]*Process, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Connections() ([]net.NetConnectionStat, error) {
|
||||||
|
return nil, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) IsRunning() (bool, error) {
|
||||||
|
return true, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
|
||||||
|
ret := make([]MemoryMapsStat, 0)
|
||||||
|
return &ret, common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProcess(pid int32) (*Process, error) {
|
||||||
|
p := &Process{Pid: pid}
|
||||||
|
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) SendSignal(sig syscall.Signal) error {
|
||||||
|
return common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) Suspend() error {
|
||||||
|
return common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Resume() error {
|
||||||
|
return common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Terminate() error {
|
||||||
|
return common.NotImplementedError
|
||||||
|
}
|
||||||
|
func (p *Process) Kill() error {
|
||||||
|
return common.NotImplementedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Process) getFromSnapProcess(pid int32) (int32, int32, string, error) {
|
||||||
|
snap := w32.CreateToolhelp32Snapshot(w32.TH32CS_SNAPPROCESS, uint32(pid))
|
||||||
|
if snap == 0 {
|
||||||
|
return 0, 0, "", syscall.GetLastError()
|
||||||
|
}
|
||||||
|
defer w32.CloseHandle(snap)
|
||||||
|
var pe32 w32.PROCESSENTRY32
|
||||||
|
pe32.DwSize = uint32(unsafe.Sizeof(pe32))
|
||||||
|
if w32.Process32First(snap, &pe32) == false {
|
||||||
|
return 0, 0, "", syscall.GetLastError()
|
||||||
|
}
|
||||||
|
|
||||||
|
if pe32.Th32ProcessID == uint32(pid) {
|
||||||
|
szexe := syscall.UTF16ToString(pe32.SzExeFile[:])
|
||||||
|
return int32(pe32.Th32ParentProcessID), int32(pe32.CntThreads), szexe, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for w32.Process32Next(snap, &pe32) {
|
||||||
|
if pe32.Th32ProcessID == uint32(pid) {
|
||||||
|
szexe := syscall.UTF16ToString(pe32.SzExeFile[:])
|
||||||
|
return int32(pe32.Th32ParentProcessID), int32(pe32.CntThreads), szexe, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, 0, "", errors.New("Couldn't find pid:" + string(pid))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get processes
|
||||||
|
func processes() ([]*Process, error) {
|
||||||
|
|
||||||
|
var dst []Win32_Process
|
||||||
|
q := wmi.CreateQuery(&dst, "")
|
||||||
|
err := wmi.Query(q, &dst)
|
||||||
|
if err != nil {
|
||||||
|
return []*Process{}, err
|
||||||
|
}
|
||||||
|
if len(dst) == 0 {
|
||||||
|
return []*Process{}, fmt.Errorf("could not get Process")
|
||||||
|
}
|
||||||
|
results := make([]*Process, 0, len(dst))
|
||||||
|
for _, proc := range dst {
|
||||||
|
p, err := NewProcess(int32(proc.ProcessId))
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
results = append(results, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProcInfo(pid int32) (*SystemProcessInformation, error) {
|
||||||
|
initialBufferSize := uint64(0x4000)
|
||||||
|
bufferSize := initialBufferSize
|
||||||
|
buffer := make([]byte, bufferSize)
|
||||||
|
|
||||||
|
var sysProcInfo SystemProcessInformation
|
||||||
|
ret, _, _ := common.ProcNtQuerySystemInformation.Call(
|
||||||
|
uintptr(unsafe.Pointer(&sysProcInfo)),
|
||||||
|
uintptr(unsafe.Pointer(&buffer[0])),
|
||||||
|
uintptr(unsafe.Pointer(&bufferSize)),
|
||||||
|
uintptr(unsafe.Pointer(&bufferSize)))
|
||||||
|
if ret != 0 {
|
||||||
|
return nil, syscall.GetLastError()
|
||||||
|
}
|
||||||
|
|
||||||
|
return &sysProcInfo, nil
|
||||||
|
}
|
160
Godeps/_workspace/src/github.com/shirou/gopsutil/process/types_darwin.go
generated
vendored
Normal file
160
Godeps/_workspace/src/github.com/shirou/gopsutil/process/types_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Hand Writing
|
||||||
|
// - all pointer in ExternProc to uint64
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input to cgo -godefs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// +godefs map struct_in_addr [4]byte /* in_addr */
|
||||||
|
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
||||||
|
// +godefs map struct_ [16]byte /* in6_addr */
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define __DARWIN_UNIX03 0
|
||||||
|
#define KERNEL
|
||||||
|
#define _DARWIN_USE_64_BIT_INODE
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <mach/message.h>
|
||||||
|
#include <sys/event.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/signal.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <net/bpf.h>
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
#include <net/if_var.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#include <sys/ucred.h>
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/_types/_timeval.h>
|
||||||
|
#include <sys/appleapiopts.h>
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <bsm/audit.h>
|
||||||
|
#include <sys/queue.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
sizeofPtr = sizeof(void*),
|
||||||
|
};
|
||||||
|
|
||||||
|
union sockaddr_all {
|
||||||
|
struct sockaddr s1; // this one gets used for fields
|
||||||
|
struct sockaddr_in s2; // these pad it out
|
||||||
|
struct sockaddr_in6 s3;
|
||||||
|
struct sockaddr_un s4;
|
||||||
|
struct sockaddr_dl s5;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sockaddr_any {
|
||||||
|
struct sockaddr addr;
|
||||||
|
char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ucred_queue {
|
||||||
|
struct ucred *tqe_next;
|
||||||
|
struct ucred **tqe_prev;
|
||||||
|
TRACEBUF
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// Machine characteristics; for internal use.
|
||||||
|
|
||||||
|
const (
|
||||||
|
sizeofPtr = C.sizeofPtr
|
||||||
|
sizeofShort = C.sizeof_short
|
||||||
|
sizeofInt = C.sizeof_int
|
||||||
|
sizeofLong = C.sizeof_long
|
||||||
|
sizeofLongLong = C.sizeof_longlong
|
||||||
|
)
|
||||||
|
|
||||||
|
// Basic types
|
||||||
|
|
||||||
|
type (
|
||||||
|
_C_short C.short
|
||||||
|
_C_int C.int
|
||||||
|
_C_long C.long
|
||||||
|
_C_long_long C.longlong
|
||||||
|
)
|
||||||
|
|
||||||
|
// Time
|
||||||
|
|
||||||
|
type Timespec C.struct_timespec
|
||||||
|
|
||||||
|
type Timeval C.struct_timeval
|
||||||
|
|
||||||
|
// Processes
|
||||||
|
|
||||||
|
type Rusage C.struct_rusage
|
||||||
|
|
||||||
|
type Rlimit C.struct_rlimit
|
||||||
|
|
||||||
|
type UGid_t C.gid_t
|
||||||
|
|
||||||
|
type KinfoProc C.struct_kinfo_proc
|
||||||
|
|
||||||
|
type Eproc C.struct_eproc
|
||||||
|
|
||||||
|
type Proc C.struct_proc
|
||||||
|
|
||||||
|
type Session C.struct_session
|
||||||
|
|
||||||
|
type ucred C.struct_ucred
|
||||||
|
|
||||||
|
type Uucred C.struct__ucred
|
||||||
|
|
||||||
|
type Upcred C.struct__pcred
|
||||||
|
|
||||||
|
type Vmspace C.struct_vmspace
|
||||||
|
|
||||||
|
type Sigacts C.struct_sigacts
|
||||||
|
|
||||||
|
type ExternProc C.struct_extern_proc
|
||||||
|
|
||||||
|
type Itimerval C.struct_itimerval
|
||||||
|
|
||||||
|
type Vnode C.struct_vnode
|
||||||
|
|
||||||
|
type Pgrp C.struct_pgrp
|
||||||
|
|
||||||
|
type UserStruct C.struct_user
|
||||||
|
|
||||||
|
type Au_session C.struct_au_session
|
||||||
|
|
||||||
|
type Posix_cred C.struct_posix_cred
|
||||||
|
|
||||||
|
type Label C.struct_label
|
||||||
|
|
||||||
|
type AuditinfoAddr C.struct_auditinfo_addr
|
||||||
|
type AuMask C.struct_au_mask
|
||||||
|
type AuTidAddr C.struct_au_tid_addr
|
||||||
|
|
||||||
|
// TAILQ(ucred)
|
||||||
|
type UcredQueue C.struct_ucred_queue
|
|
@ -12,7 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Specification struct {
|
type Specification struct {
|
||||||
PidFile string `toml:pid_file`
|
PidFile string
|
||||||
Exe string
|
Exe string
|
||||||
Prefix string
|
Prefix string
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue