godep update for procstat
This commit is contained in:
parent
fdf00c1be6
commit
5cc26bb640
|
@ -195,6 +195,11 @@
|
|||
"Comment": "1.0.0-161-g3303647",
|
||||
"Rev": "3303647209557312e5db51450ea8bbdef56d5176"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/host",
|
||||
"Comment": "1.0.0-153-gc1313e7",
|
||||
"Rev": "c1313e76341b18456212c5645d1daa7f132ac50e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/load",
|
||||
"Comment": "1.0.0-161-g3303647",
|
||||
|
@ -210,6 +215,11 @@
|
|||
"Comment": "1.0.0-161-g3303647",
|
||||
"Rev": "3303647209557312e5db51450ea8bbdef56d5176"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/process",
|
||||
"Comment": "1.0.0-153-gc1313e7",
|
||||
"Rev": "c1313e76341b18456212c5645d1daa7f132ac50e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/streadway/amqp",
|
||||
"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 {
|
||||
PidFile string `toml:pid_file`
|
||||
PidFile string
|
||||
Exe string
|
||||
Prefix string
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue