Agent 默认不采集 disk.rw.error 指标 (#455)

* configurable FsRWMetrics collect
This commit is contained in:
qinyening 2020-12-12 17:27:57 +08:00 committed by GitHub
parent 2e7a2a07ac
commit 9b0a8dbb07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 1216 additions and 1358 deletions

2
go.mod
View File

@ -26,7 +26,7 @@ require (
github.com/pquerna/cachecontrol v0.0.0-20200819021114-67c6ae64274f // indirect github.com/pquerna/cachecontrol v0.0.0-20200819021114-67c6ae64274f // indirect
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62 // indirect github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62 // indirect
github.com/shirou/gopsutil v2.20.7+incompatible github.com/shirou/gopsutil v3.20.11+incompatible
github.com/spaolacci/murmur3 v1.1.0 github.com/spaolacci/murmur3 v1.1.0
github.com/spf13/viper v1.7.1 github.com/spf13/viper v1.7.1
github.com/streadway/amqp v1.0.0 github.com/streadway/amqp v1.0.0

2
go.sum
View File

@ -782,6 +782,8 @@ github.com/shirou/gopsutil v2.17.13-0.20180801053943-8048a2e9c577+incompatible/g
github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v2.20.7+incompatible h1:Ymv4OD12d6zm+2yONe39VSmp2XooJe8za7ngOLW/o/w= github.com/shirou/gopsutil v2.20.7+incompatible h1:Ymv4OD12d6zm+2yONe39VSmp2XooJe8za7ngOLW/o/w=
github.com/shirou/gopsutil v2.20.7+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v2.20.7+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v3.20.11+incompatible h1:LJr4ZQK4mPpIV5gOa4jCOKOGb4ty4DZO54I4FGqIpto=
github.com/shirou/gopsutil v3.20.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=

View File

@ -63,7 +63,8 @@ func gatherFields(m map[string]string) (map[string]string, error) {
for k, v := range m { for k, v := range m {
output, err := exec(v) output, err := exec(v)
if err != nil { if err != nil {
return nil, err logger.Errorf("get %s by exec %v err:%v", k, v, err)
continue
} }
ret[k] = output ret[k] = output
} }

View File

@ -11,6 +11,7 @@ type SysSection struct {
PluginRemote bool `yaml:"pluginRemote"` PluginRemote bool `yaml:"pluginRemote"`
Interval int `yaml:"interval"` Interval int `yaml:"interval"`
Timeout int `yaml:"timeout"` Timeout int `yaml:"timeout"`
FsRWEnable bool `yaml:"fsRWEnable"`
} }
type MountIgnoreSection struct { type MountIgnoreSection struct {

View File

@ -29,7 +29,6 @@ func BuildMappers() {
IOStatsMetrics, IOStatsMetrics,
NfMetrics, NfMetrics,
FsKernelMetrics, FsKernelMetrics,
FsRWMetrics,
ProcsNumMetrics, ProcsNumMetrics,
EntityNumMetrics, EntityNumMetrics,
NtpOffsetMetrics, NtpOffsetMetrics,
@ -46,6 +45,17 @@ func BuildMappers() {
Interval: interval, Interval: interval,
}, },
} }
if sys.Config.FsRWEnable {
Mapper := FuncsAndInterval{
Fs: []func() []*dataobj.MetricValue{
FsRWMetrics,
},
Interval: interval,
}
Mappers = append(Mappers, Mapper)
}
} else { } else {
log.Println("sys collect enable is false.") log.Println("sys collect enable is false.")
Mappers = []FuncsAndInterval{ Mappers = []FuncsAndInterval{

View File

@ -149,7 +149,9 @@ func PercentWithContext(ctx context.Context, interval time.Duration, percpu bool
return nil, err return nil, err
} }
time.Sleep(interval) if err := common.Sleep(ctx, interval); err != nil {
return nil, err
}
// And at the end of the interval. // And at the end of the interval.
cpuTimes2, err := Times(percpu) cpuTimes2, err := Times(percpu)

View File

@ -7,6 +7,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os/exec" "os/exec"
"path/filepath"
"strconv" "strconv"
"strings" "strings"
@ -311,7 +312,29 @@ func CountsWithContext(ctx context.Context, logical bool) (int, error) {
} }
return ret, nil return ret, nil
} }
// physical cores https://github.com/giampaolo/psutil/blob/d01a9eaa35a8aadf6c519839e987a49d8be2d891/psutil/_pslinux.py#L628 // physical cores
// https://github.com/giampaolo/psutil/blob/8415355c8badc9c94418b19bdf26e622f06f0cce/psutil/_pslinux.py#L615-L628
var threadSiblingsLists = make(map[string]bool)
// These 2 files are the same but */core_cpus_list is newer while */thread_siblings_list is deprecated and may disappear in the future.
// https://www.kernel.org/doc/Documentation/admin-guide/cputopology.rst
// https://github.com/giampaolo/psutil/pull/1727#issuecomment-707624964
// https://lkml.org/lkml/2019/2/26/41
for _, glob := range []string{"devices/system/cpu/cpu[0-9]*/topology/core_cpus_list", "devices/system/cpu/cpu[0-9]*/topology/thread_siblings_list"} {
if files, err := filepath.Glob(common.HostSys(glob)); err == nil {
for _, file := range files {
lines, err := common.ReadLines(file)
if err != nil || len(lines) != 1 {
continue
}
threadSiblingsLists[lines[0]] = true
}
ret := len(threadSiblingsLists)
if ret != 0 {
return ret, nil
}
}
}
// https://github.com/giampaolo/psutil/blob/122174a10b75c9beebe15f6c07dcf3afbe3b120d/psutil/_pslinux.py#L631-L652
filename := common.HostProc("cpuinfo") filename := common.HostProc("cpuinfo")
lines, err := common.ReadLines(filename) lines, err := common.ReadLines(filename)
if err != nil { if err != nil {

View File

@ -32,7 +32,6 @@ const (
CTLKern = 1 // "high kernel": proc, limits CTLKern = 1 // "high kernel": proc, limits
CTLHw = 6 // CTL_HW CTLHw = 6 // CTL_HW
SMT = 24 // HW_SMT SMT = 24 // HW_SMT
NCpuOnline = 25 // HW_NCPUONLINE
KernCptime = 40 // KERN_CPTIME KernCptime = 40 // KERN_CPTIME
KernCptime2 = 71 // KERN_CPTIME2 KernCptime2 = 71 // KERN_CPTIME2
) )
@ -163,25 +162,17 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
c := InfoStat{} c := InfoStat{}
var u32 uint32 mhz, err := unix.SysctlUint32("hw.cpuspeed")
if u32, err = unix.SysctlUint32("hw.cpuspeed"); err != nil {
return nil, err
}
c.Mhz = float64(u32)
mib := []int32{CTLHw, NCpuOnline}
buf, _, err := common.CallSyscall(mib)
if err != nil { if err != nil {
return nil, err return nil, err
} }
c.Mhz = float64(mhz)
var ncpu int32 ncpu, err := unix.SysctlUint32("hw.ncpuonline")
br := bytes.NewReader(buf)
err = binary.Read(br, binary.LittleEndian, &ncpu)
if err != nil { if err != nil {
return nil, err return nil, err
} }
c.Cores = ncpu c.Cores = int32(ncpu)
if c.ModelName, err = unix.Sysctl("hw.model"); err != nil { if c.ModelName, err = unix.Sysctl("hw.model"); err != nil {
return nil, err return nil, err

View File

@ -326,7 +326,6 @@ func GetEnv(key string, dfault string, combineWith ...string) string {
copy(all[1:], combineWith) copy(all[1:], combineWith)
return filepath.Join(all...) return filepath.Join(all...)
} }
panic("invalid switch case")
} }
func HostProc(combineWith ...string) string { func HostProc(combineWith ...string) string {

View File

@ -36,7 +36,7 @@ func CallSyscall(mib []int32) ([]byte, uint64, error) {
// get required buffer size // get required buffer size
length := uint64(0) length := uint64(0)
_, _, err := unix.Syscall6( _, _, err := unix.Syscall6(
unix.SYS___SYSCTL, 202, // unix.SYS___SYSCTL https://github.com/golang/sys/blob/76b94024e4b621e672466e8db3d7f084e7ddcad2/unix/zsysnum_darwin_amd64.go#L146
uintptr(unsafe.Pointer(&mib[0])), uintptr(unsafe.Pointer(&mib[0])),
uintptr(miblen), uintptr(miblen),
0, 0,
@ -54,7 +54,7 @@ func CallSyscall(mib []int32) ([]byte, uint64, error) {
// get proc info itself // get proc info itself
buf := make([]byte, length) buf := make([]byte, length)
_, _, err = unix.Syscall6( _, _, err = unix.Syscall6(
unix.SYS___SYSCTL, 202, // unix.SYS___SYSCTL https://github.com/golang/sys/blob/76b94024e4b621e672466e8db3d7f084e7ddcad2/unix/zsysnum_darwin_amd64.go#L146
uintptr(unsafe.Pointer(&mib[0])), uintptr(unsafe.Pointer(&mib[0])),
uintptr(miblen), uintptr(miblen),
uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&buf[0])),

View File

@ -10,6 +10,7 @@ import (
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
) )
@ -110,9 +111,24 @@ func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background()) return VirtualizationWithContext(context.Background())
} }
// required variables for concurrency safe virtualization caching
var (
cachedVirtMap map[string]string
cachedVirtMutex sync.RWMutex
cachedVirtOnce sync.Once
)
func VirtualizationWithContext(ctx context.Context) (string, string, error) { func VirtualizationWithContext(ctx context.Context) (string, string, error) {
var system string var system, role string
var role string
// if cached already, return from cache
cachedVirtMutex.RLock() // unlock won't be deferred so concurrent reads don't wait for long
if cachedVirtMap != nil {
cachedSystem, cachedRole := cachedVirtMap["system"], cachedVirtMap["role"]
cachedVirtMutex.RUnlock()
return cachedSystem, cachedRole, nil
}
cachedVirtMutex.RUnlock()
filename := HostProc("xen") filename := HostProc("xen")
if PathExists(filename) { if PathExists(filename) {
@ -231,6 +247,17 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) {
role = "host" role = "host"
} }
} }
// before returning for the first time, cache the system and role
cachedVirtOnce.Do(func() {
cachedVirtMutex.Lock()
defer cachedVirtMutex.Unlock()
cachedVirtMap = map[string]string{
"system": system,
"role": role,
}
})
return system, role, nil return system, role, nil
} }

View File

@ -4,6 +4,7 @@ package common
import ( import (
"context" "context"
"fmt"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall" "syscall"
@ -93,7 +94,7 @@ func BytePtrToString(p *uint8) string {
return string(a[:i]) return string(a[:i])
} }
// CounterInfo // CounterInfo struct is used to track a windows performance counter
// copied from https://github.com/mackerelio/mackerel-agent/ // copied from https://github.com/mackerelio/mackerel-agent/
type CounterInfo struct { type CounterInfo struct {
PostName string PostName string
@ -101,7 +102,7 @@ type CounterInfo struct {
Counter windows.Handle Counter windows.Handle
} }
// CreateQuery XXX // CreateQuery with a PdhOpenQuery call
// copied from https://github.com/mackerelio/mackerel-agent/ // copied from https://github.com/mackerelio/mackerel-agent/
func CreateQuery() (windows.Handle, error) { func CreateQuery() (windows.Handle, error) {
var query windows.Handle var query windows.Handle
@ -112,7 +113,7 @@ func CreateQuery() (windows.Handle, error) {
return query, nil return query, nil
} }
// CreateCounter XXX // CreateCounter with a PdhAddCounter call
func CreateCounter(query windows.Handle, pname, cname string) (*CounterInfo, error) { func CreateCounter(query windows.Handle, pname, cname string) (*CounterInfo, error) {
var counter windows.Handle var counter windows.Handle
r, _, err := PdhAddCounter.Call( r, _, err := PdhAddCounter.Call(
@ -130,6 +131,62 @@ func CreateCounter(query windows.Handle, pname, cname string) (*CounterInfo, err
}, nil }, nil
} }
// GetCounterValue get counter value from handle
// adapted from https://github.com/mackerelio/mackerel-agent/
func GetCounterValue(counter windows.Handle) (float64, error) {
var value PDH_FMT_COUNTERVALUE_DOUBLE
r, _, err := PdhGetFormattedCounterValue.Call(uintptr(counter), PDH_FMT_DOUBLE, uintptr(0), uintptr(unsafe.Pointer(&value)))
if r != 0 && r != PDH_INVALID_DATA {
return 0.0, err
}
return value.DoubleValue, nil
}
type Win32PerformanceCounter struct {
PostName string
CounterName string
Query windows.Handle
Counter windows.Handle
}
func NewWin32PerformanceCounter(postName, counterName string) (*Win32PerformanceCounter, error) {
query, err := CreateQuery()
if err != nil {
return nil, err
}
var counter = Win32PerformanceCounter{
Query: query,
PostName: postName,
CounterName: counterName,
}
r, _, err := PdhAddCounter.Call(
uintptr(counter.Query),
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(counter.CounterName))),
0,
uintptr(unsafe.Pointer(&counter.Counter)),
)
if r != 0 {
return nil, err
}
return &counter, nil
}
func (w *Win32PerformanceCounter) GetValue() (float64, error) {
r, _, err := PdhCollectQueryData.Call(uintptr(w.Query))
if r != 0 && err != nil {
if r == PDH_NO_DATA {
return 0.0, fmt.Errorf("%w: this counter has not data", err)
}
return 0.0, err
}
return GetCounterValue(w.Counter)
}
func ProcessorQueueLengthCounter() (*Win32PerformanceCounter, error) {
return NewWin32PerformanceCounter("processor_queue_length", `\System\Processor Queue Length`)
}
// WMIQueryWithContext - wraps wmi.Query with a timed-out context to avoid hanging // WMIQueryWithContext - wraps wmi.Query with a timed-out context to avoid hanging
func WMIQueryWithContext(ctx context.Context, query string, dst interface{}, connectServerArgs ...interface{}) error { func WMIQueryWithContext(ctx context.Context, query string, dst interface{}, connectServerArgs ...interface{}) error {
if _, ok := ctx.Deadline(); !ok { if _, ok := ctx.Deadline(); !ok {

View File

@ -0,0 +1,18 @@
package common
import (
"context"
"time"
)
// Sleep awaits for provided interval.
// Can be interrupted by context cancelation.
func Sleep(ctx context.Context, interval time.Duration) error {
var timer = time.NewTimer(interval)
select {
case <-ctx.Done():
return ctx.Err()
case <-timer.C:
return nil
}
}

View File

@ -73,86 +73,226 @@ func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *Virtu
value := strings.TrimSpace(fields[1]) value := strings.TrimSpace(fields[1])
value = strings.Replace(value, " kB", "", -1) value = strings.Replace(value, " kB", "", -1)
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx,err
}
switch key { switch key {
case "MemTotal": case "MemTotal":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Total = t * 1024 ret.Total = t * 1024
case "MemFree": case "MemFree":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Free = t * 1024 ret.Free = t * 1024
case "MemAvailable": case "MemAvailable":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
memavail = true memavail = true
ret.Available = t * 1024 ret.Available = t * 1024
case "Buffers": case "Buffers":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Buffers = t * 1024 ret.Buffers = t * 1024
case "Cached": case "Cached":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Cached = t * 1024 ret.Cached = t * 1024
case "Active": case "Active":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Active = t * 1024 ret.Active = t * 1024
case "Inactive": case "Inactive":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Inactive = t * 1024 ret.Inactive = t * 1024
case "Active(anon)": case "Active(anon)":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
retEx.ActiveAnon = t * 1024 retEx.ActiveAnon = t * 1024
case "Inactive(anon)": case "Inactive(anon)":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
retEx.InactiveAnon = t * 1024 retEx.InactiveAnon = t * 1024
case "Active(file)": case "Active(file)":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
activeFile = true activeFile = true
retEx.ActiveFile = t * 1024 retEx.ActiveFile = t * 1024
case "Inactive(file)": case "Inactive(file)":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
inactiveFile = true inactiveFile = true
retEx.InactiveFile = t * 1024 retEx.InactiveFile = t * 1024
case "Unevictable": case "Unevictable":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
retEx.Unevictable = t * 1024 retEx.Unevictable = t * 1024
case "Writeback": case "Writeback":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Writeback = t * 1024 ret.Writeback = t * 1024
case "WritebackTmp": case "WritebackTmp":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.WritebackTmp = t * 1024 ret.WritebackTmp = t * 1024
case "Dirty": case "Dirty":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Dirty = t * 1024 ret.Dirty = t * 1024
case "Shmem": case "Shmem":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Shared = t * 1024 ret.Shared = t * 1024
case "Slab": case "Slab":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Slab = t * 1024 ret.Slab = t * 1024
case "SReclaimable": case "SReclaimable":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
sReclaimable = true sReclaimable = true
ret.SReclaimable = t * 1024 ret.SReclaimable = t * 1024
case "SUnreclaim": case "SUnreclaim":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.SUnreclaim = t * 1024 ret.SUnreclaim = t * 1024
case "PageTables": case "PageTables":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.PageTables = t * 1024 ret.PageTables = t * 1024
case "SwapCached": case "SwapCached":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.SwapCached = t * 1024 ret.SwapCached = t * 1024
case "CommitLimit": case "CommitLimit":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.CommitLimit = t * 1024 ret.CommitLimit = t * 1024
case "Committed_AS": case "Committed_AS":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.CommittedAS = t * 1024 ret.CommittedAS = t * 1024
case "HighTotal": case "HighTotal":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.HighTotal = t * 1024 ret.HighTotal = t * 1024
case "HighFree": case "HighFree":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.HighFree = t * 1024 ret.HighFree = t * 1024
case "LowTotal": case "LowTotal":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.LowTotal = t * 1024 ret.LowTotal = t * 1024
case "LowFree": case "LowFree":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.LowFree = t * 1024 ret.LowFree = t * 1024
case "SwapTotal": case "SwapTotal":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.SwapTotal = t * 1024 ret.SwapTotal = t * 1024
case "SwapFree": case "SwapFree":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.SwapFree = t * 1024 ret.SwapFree = t * 1024
case "Mapped": case "Mapped":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Mapped = t * 1024 ret.Mapped = t * 1024
case "VmallocTotal": case "VmallocTotal":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.VMallocTotal = t * 1024 ret.VMallocTotal = t * 1024
case "VmallocUsed": case "VmallocUsed":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.VMallocUsed = t * 1024 ret.VMallocUsed = t * 1024
case "VmallocChunk": case "VmallocChunk":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.VMallocChunk = t * 1024 ret.VMallocChunk = t * 1024
case "HugePages_Total": case "HugePages_Total":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.HugePagesTotal = t ret.HugePagesTotal = t
case "HugePages_Free": case "HugePages_Free":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.HugePagesFree = t ret.HugePagesFree = t
case "Hugepagesize": case "Hugepagesize":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.HugePageSize = t * 1024 ret.HugePageSize = t * 1024
} }
} }

View File

@ -11,6 +11,7 @@ import (
"os/exec" "os/exec"
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
"golang.org/x/sys/unix"
) )
func GetPageSize() (uint64, error) { func GetPageSize() (uint64, error) {
@ -18,17 +19,7 @@ func GetPageSize() (uint64, error) {
} }
func GetPageSizeWithContext(ctx context.Context) (uint64, error) { func GetPageSizeWithContext(ctx context.Context) (uint64, error) {
mib := []int32{CTLVm, VmUvmexp} uvmexp, err := unix.SysctlUvmexp("vm.uvmexp")
buf, length, err := common.CallSyscall(mib)
if err != nil {
return 0, err
}
if length < sizeOfUvmexp {
return 0, fmt.Errorf("short syscall ret %d bytes", length)
}
var uvmexp Uvmexp
br := bytes.NewReader(buf)
err = common.Read(br, binary.LittleEndian, &uvmexp)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -40,17 +31,7 @@ func VirtualMemory() (*VirtualMemoryStat, error) {
} }
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
mib := []int32{CTLVm, VmUvmexp} uvmexp, err := unix.SysctlUvmexp("vm.uvmexp")
buf, length, err := common.CallSyscall(mib)
if err != nil {
return nil, err
}
if length < sizeOfUvmexp {
return nil, fmt.Errorf("short syscall ret %d bytes", length)
}
var uvmexp Uvmexp
br := bytes.NewReader(buf)
err = common.Read(br, binary.LittleEndian, &uvmexp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -69,8 +50,8 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
ret.Used = ret.Total - ret.Available ret.Used = ret.Total - ret.Available
ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0 ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0
mib = []int32{CTLVfs, VfsGeneric, VfsBcacheStat} mib := []int32{CTLVfs, VfsGeneric, VfsBcacheStat}
buf, length, err = common.CallSyscall(mib) buf, length, err := common.CallSyscall(mib)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -78,7 +59,7 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
return nil, fmt.Errorf("short syscall ret %d bytes", length) return nil, fmt.Errorf("short syscall ret %d bytes", length)
} }
var bcs Bcachestats var bcs Bcachestats
br = bytes.NewReader(buf) br := bytes.NewReader(buf)
err = common.Read(br, binary.LittleEndian, &bcs) err = common.Read(br, binary.LittleEndian, &bcs)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -0,0 +1,37 @@
// +build openbsd
// +build 386
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs mem/types_openbsd.go
package mem
const (
CTLVfs = 10
VfsGeneric = 0
VfsBcacheStat = 3
)
const (
sizeOfBcachestats = 0x90
)
type Bcachestats struct {
Numbufs int64
Numbufpages int64
Numdirtypages int64
Numcleanpages int64
Pendingwrites int64
Pendingreads int64
Numwrites int64
Numreads int64
Cachehits int64
Busymapped int64
Dmapages int64
Highpages int64
Delwribufs int64
Kvaslots int64
Avail int64
Highflips int64
Highflops int64
Dmaflips int64
}

View File

@ -4,105 +4,15 @@
package mem package mem
const ( const (
CTLVm = 2
CTLVfs = 10 CTLVfs = 10
VmUvmexp = 4
VfsGeneric = 0 VfsGeneric = 0
VfsBcacheStat = 3 VfsBcacheStat = 3
) )
const ( const (
sizeOfUvmexp = 0x154
sizeOfBcachestats = 0x78 sizeOfBcachestats = 0x78
) )
type Uvmexp struct {
Pagesize int32
Pagemask int32
Pageshift int32
Npages int32
Free int32
Active int32
Inactive int32
Paging int32
Wired int32
Zeropages int32
Reserve_pagedaemon int32
Reserve_kernel int32
Anonpages int32
Vnodepages int32
Vtextpages int32
Freemin int32
Freetarg int32
Inactarg int32
Wiredmax int32
Anonmin int32
Vtextmin int32
Vnodemin int32
Anonminpct int32
Vtextminpct int32
Vnodeminpct int32
Nswapdev int32
Swpages int32
Swpginuse int32
Swpgonly int32
Nswget int32
Nanon int32
Nanonneeded int32
Nfreeanon int32
Faults int32
Traps int32
Intrs int32
Swtch int32
Softs int32
Syscalls int32
Pageins int32
Obsolete_swapins int32
Obsolete_swapouts int32
Pgswapin int32
Pgswapout int32
Forks int32
Forks_ppwait int32
Forks_sharevm int32
Pga_zerohit int32
Pga_zeromiss int32
Zeroaborts int32
Fltnoram int32
Fltnoanon int32
Fltpgwait int32
Fltpgrele int32
Fltrelck int32
Fltrelckok int32
Fltanget int32
Fltanretry int32
Fltamcopy int32
Fltnamap int32
Fltnomap int32
Fltlget int32
Fltget int32
Flt_anon int32
Flt_acow int32
Flt_obj int32
Flt_prcopy int32
Flt_przero int32
Pdwoke int32
Pdrevs int32
Pdswout int32
Pdfreed int32
Pdscans int32
Pdanscan int32
Pdobscan int32
Pdreact int32
Pdbusy int32
Pdpageouts int32
Pdpending int32
Pddeact int32
Pdreanon int32
Pdrevnode int32
Pdrevtext int32
Fpswtch int32
Kmapent int32
}
type Bcachestats struct { type Bcachestats struct {
Numbufs int64 Numbufs int64
Numbufpages int64 Numbufpages int64

View File

@ -269,7 +269,7 @@ func FilterCounters() ([]FilterStat, error) {
} }
func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) {
return nil, errors.New("NetFilterCounters not implemented for darwin") return nil, common.ErrNotImplementedError
} }
func ConntrackStats(percpu bool) ([]ConntrackStat, error) { func ConntrackStats(percpu bool) ([]ConntrackStat, error) {
@ -289,5 +289,5 @@ func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
} }
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for darwin") return nil, common.ErrNotImplementedError
} }

View File

@ -4,7 +4,6 @@ package net
import ( import (
"context" "context"
"errors"
"os/exec" "os/exec"
"strconv" "strconv"
"strings" "strings"
@ -109,7 +108,7 @@ func FilterCounters() ([]FilterStat, error) {
} }
func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) {
return nil, errors.New("NetFilterCounters not implemented for freebsd") return nil, common.ErrNotImplementedError
} }
func ConntrackStats(percpu bool) ([]ConntrackStat, error) { func ConntrackStats(percpu bool) ([]ConntrackStat, error) {
@ -117,7 +116,7 @@ func ConntrackStats(percpu bool) ([]ConntrackStat, error) {
} }
func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackStat, error) { func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackStat, error) {
return nil, errors.New("ConntrackStats not implemented for freebsd") return nil, common.ErrNotImplementedError
} }
// NetProtoCounters returns network statistics for the entire system // NetProtoCounters returns network statistics for the entire system
@ -129,5 +128,5 @@ func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
} }
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for freebsd") return nil, common.ErrNotImplementedError
} }

View File

@ -696,7 +696,7 @@ func decodeAddress(family uint32, src string) (Addr, error) {
return Addr{}, fmt.Errorf("does not contain port, %s", src) return Addr{}, fmt.Errorf("does not contain port, %s", src)
} }
addr := t[0] addr := t[0]
port, err := strconv.ParseInt("0x"+t[1], 0, 64) port, err := strconv.ParseUint(t[1], 16, 16)
if err != nil { if err != nil {
return Addr{}, fmt.Errorf("invalid port, %s", src) return Addr{}, fmt.Errorf("invalid port, %s", src)
} }

View File

@ -4,7 +4,6 @@ package net
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"os/exec" "os/exec"
"regexp" "regexp"
@ -153,7 +152,7 @@ func FilterCounters() ([]FilterStat, error) {
} }
func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) {
return nil, errors.New("NetFilterCounters not implemented for openbsd") return nil, common.ErrNotImplementedError
} }
func ConntrackStats(percpu bool) ([]ConntrackStat, error) { func ConntrackStats(percpu bool) ([]ConntrackStat, error) {
@ -173,7 +172,7 @@ func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
} }
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for openbsd") return nil, common.ErrNotImplementedError
} }
func parseNetstatLine(line string) (ConnectionStat, error) { func parseNetstatLine(line string) (ConnectionStat, error) {

View File

@ -4,7 +4,6 @@ package net
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"net" "net"
"os" "os"
@ -323,7 +322,7 @@ func FilterCounters() ([]FilterStat, error) {
} }
func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) {
return nil, errors.New("NetFilterCounters not implemented for windows") return nil, common.ErrNotImplementedError
} }
func ConntrackStats(percpu bool) ([]ConntrackStat, error) { func ConntrackStats(percpu bool) ([]ConntrackStat, error) {
@ -344,7 +343,7 @@ func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
} }
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for windows") return nil, common.ErrNotImplementedError
} }
func getTableUintptr(family uint32, buf []byte) uintptr { func getTableUintptr(family uint32, buf []byte) uintptr {
@ -548,7 +547,7 @@ func getUDPConnections(family uint32) ([]ConnectionStat, error) {
mibs := (*mibUDPRowOwnerPid)(unsafe.Pointer(&buf[index])) mibs := (*mibUDPRowOwnerPid)(unsafe.Pointer(&buf[index]))
ns := mibs.convertToConnectionStat() ns := mibs.convertToConnectionStat()
stats = append(stats, ns) stats = append(stats, ns)
case kindUDP4.family: case kindUDP6.family:
mibs := (*mibUDP6RowOwnerPid)(unsafe.Pointer(&buf[index])) mibs := (*mibUDP6RowOwnerPid)(unsafe.Pointer(&buf[index]))
ns := mibs.convertToConnectionStat() ns := mibs.convertToConnectionStat()
stats = append(stats, ns) stats = append(stats, ns)

View File

@ -6,11 +6,14 @@ import (
"errors" "errors"
"runtime" "runtime"
"sort" "sort"
"sync"
"syscall"
"time" "time"
"github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/mem" "github.com/shirou/gopsutil/mem"
"github.com/shirou/gopsutil/net"
) )
var ( var (
@ -24,6 +27,7 @@ type Process struct {
name string name string
status string status string
parent int32 parent int32
parentMutex *sync.RWMutex // for windows ppid cache
numCtxSwitches *NumCtxSwitchesStat numCtxSwitches *NumCtxSwitchesStat
uids []int32 uids []int32
gids []int32 gids []int32
@ -150,21 +154,34 @@ func PidsWithContext(ctx context.Context) ([]int32, error) {
return pids, err return pids, err
} }
// Processes returns a slice of pointers to Process structs for all
// currently running processes.
func Processes() ([]*Process, error) {
return ProcessesWithContext(context.Background())
}
// NewProcess creates a new Process instance, it only stores the pid and // NewProcess creates a new Process instance, it only stores the pid and
// checks that the process exists. Other method on Process can be used // checks that the process exists. Other method on Process can be used
// to get more information about the process. An error will be returned // to get more information about the process. An error will be returned
// if the process does not exist. // if the process does not exist.
func NewProcess(pid int32) (*Process, error) { func NewProcess(pid int32) (*Process, error) {
p := &Process{Pid: pid} return NewProcessWithContext(context.Background(), pid)
}
exists, err := PidExists(pid) func NewProcessWithContext(ctx context.Context, pid int32) (*Process, error) {
p := &Process{
Pid: pid,
parentMutex: new(sync.RWMutex),
}
exists, err := PidExistsWithContext(ctx, pid)
if err != nil { if err != nil {
return p, err return p, err
} }
if !exists { if !exists {
return p, ErrorProcessNotRunning return p, ErrorProcessNotRunning
} }
p.CreateTime() p.CreateTimeWithContext(ctx)
return p, nil return p, nil
} }
@ -192,7 +209,7 @@ func (p *Process) Percent(interval time.Duration) (float64, error) {
} }
func (p *Process) PercentWithContext(ctx context.Context, interval time.Duration) (float64, error) { func (p *Process) PercentWithContext(ctx context.Context, interval time.Duration) (float64, error) {
cpuTimes, err := p.Times() cpuTimes, err := p.TimesWithContext(ctx)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -201,8 +218,10 @@ func (p *Process) PercentWithContext(ctx context.Context, interval time.Duration
if interval > 0 { if interval > 0 {
p.lastCPUTimes = cpuTimes p.lastCPUTimes = cpuTimes
p.lastCPUTime = now p.lastCPUTime = now
time.Sleep(interval) if err := common.Sleep(ctx, interval); err != nil {
cpuTimes, err = p.Times() return 0, err
}
cpuTimes, err = p.TimesWithContext(ctx)
now = time.Now() now = time.Now()
if err != nil { if err != nil {
return 0, err return 0, err
@ -234,7 +253,7 @@ func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
if err != nil { if err != nil {
return false, err return false, err
} }
p2, err := NewProcess(p.Pid) p2, err := NewProcessWithContext(ctx, p.Pid)
if err == ErrorProcessNotRunning { if err == ErrorProcessNotRunning {
return false, nil return false, nil
} }
@ -274,13 +293,13 @@ func (p *Process) MemoryPercent() (float32, error) {
} }
func (p *Process) MemoryPercentWithContext(ctx context.Context) (float32, error) { func (p *Process) MemoryPercentWithContext(ctx context.Context) (float32, error) {
machineMemory, err := mem.VirtualMemory() machineMemory, err := mem.VirtualMemoryWithContext(ctx)
if err != nil { if err != nil {
return 0, err return 0, err
} }
total := machineMemory.Total total := machineMemory.Total
processMemory, err := p.MemoryInfo() processMemory, err := p.MemoryInfoWithContext(ctx)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -295,12 +314,12 @@ func (p *Process) CPUPercent() (float64, error) {
} }
func (p *Process) CPUPercentWithContext(ctx context.Context) (float64, error) { func (p *Process) CPUPercentWithContext(ctx context.Context) (float64, error) {
crt_time, err := p.CreateTime() crt_time, err := p.createTimeWithContext(ctx)
if err != nil { if err != nil {
return 0, err return 0, err
} }
cput, err := p.Times() cput, err := p.TimesWithContext(ctx)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -318,3 +337,208 @@ func (p *Process) CPUPercentWithContext(ctx context.Context) (float64, error) {
func (p *Process) Groups() ([]int32, error) { func (p *Process) Groups() ([]int32, error) {
return p.GroupsWithContext(context.Background()) return p.GroupsWithContext(context.Background())
} }
// Ppid returns Parent Process ID of the process.
func (p *Process) Ppid() (int32, error) {
return p.PpidWithContext(context.Background())
}
// Name returns name of the process.
func (p *Process) Name() (string, error) {
return p.NameWithContext(context.Background())
}
// Exe returns executable path of the process.
func (p *Process) Exe() (string, error) {
return p.ExeWithContext(context.Background())
}
// Cmdline returns the command line arguments of the process as a string with
// each argument separated by 0x20 ascii character.
func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
// CmdlineSlice returns the command line arguments of the process as a slice with each
// element being an argument.
func (p *Process) CmdlineSlice() ([]string, error) {
return p.CmdlineSliceWithContext(context.Background())
}
// Cwd returns current working directory of the process.
func (p *Process) Cwd() (string, error) {
return p.CwdWithContext(context.Background())
}
// Parent returns parent Process of the process.
func (p *Process) Parent() (*Process, error) {
return p.ParentWithContext(context.Background())
}
// Status returns the process status.
// Return value could be one of these.
// R: Running S: Sleep T: Stop I: Idle
// Z: Zombie W: Wait L: Lock
// The character is same within all supported platforms.
func (p *Process) Status() (string, error) {
return p.StatusWithContext(context.Background())
}
// Foreground returns true if the process is in foreground, false otherwise.
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}
// Uids returns user ids of the process as a slice of the int
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
// Gids returns group ids of the process as a slice of the int
func (p *Process) Gids() ([]int32, error) {
return p.GidsWithContext(context.Background())
}
// Terminal returns a terminal which is associated with the process.
func (p *Process) Terminal() (string, error) {
return p.TerminalWithContext(context.Background())
}
// Nice returns a nice value (priority).
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
// IOnice returns process I/O nice value (priority).
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())
}
// Rlimit returns Resource Limits.
func (p *Process) Rlimit() ([]RlimitStat, error) {
return p.RlimitWithContext(context.Background())
}
// RlimitUsage returns Resource Limits.
// If gatherUsed is true, the currently used value will be gathered and added
// to the resulting RlimitStat.
func (p *Process) RlimitUsage(gatherUsed bool) ([]RlimitStat, error) {
return p.RlimitUsageWithContext(context.Background(), gatherUsed)
}
// IOCounters returns IO Counters.
func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.IOCountersWithContext(context.Background())
}
// NumCtxSwitches returns the number of the context switches of the process.
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return p.NumCtxSwitchesWithContext(context.Background())
}
// NumFDs returns the number of File Descriptors used by the process.
func (p *Process) NumFDs() (int32, error) {
return p.NumFDsWithContext(context.Background())
}
// NumThreads returns the number of threads used by the process.
func (p *Process) NumThreads() (int32, error) {
return p.NumThreadsWithContext(context.Background())
}
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
return p.ThreadsWithContext(context.Background())
}
// Times returns CPU times of the process.
func (p *Process) Times() (*cpu.TimesStat, error) {
return p.TimesWithContext(context.Background())
}
// CPUAffinity returns CPU affinity of the process.
func (p *Process) CPUAffinity() ([]int32, error) {
return p.CPUAffinityWithContext(context.Background())
}
// MemoryInfo returns generic process memory information,
// such as RSS, VMS and Swap
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
// MemoryInfoEx returns platform-specific process memory information.
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
// PageFaultsInfo returns the process's page fault counters.
func (p *Process) PageFaults() (*PageFaultsStat, error) {
return p.PageFaultsWithContext(context.Background())
}
// Children returns a slice of Process of the process.
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
// OpenFiles returns a slice of OpenFilesStat opend by the process.
// OpenFilesStat includes a file path and file descriptor.
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
// Connections returns a slice of net.ConnectionStat used by the process.
// This returns all kind of the connection. This means TCP, UDP or UNIX.
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
}
// Connections returns a slice of net.ConnectionStat used by the process at most `max`.
func (p *Process) ConnectionsMax(max int) ([]net.ConnectionStat, error) {
return p.ConnectionsMaxWithContext(context.Background(), max)
}
// NetIOCounters returns NetIOCounters of the process.
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
}
// MemoryMaps get memory maps from /proc/(pid)/smaps
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
}
// Tgid returns thread group id of the process.
func (p *Process) Tgid() (int32, error) {
return p.TgidWithContext(context.Background())
}
// SendSignal sends a unix.Signal to the process.
func (p *Process) SendSignal(sig syscall.Signal) error {
return p.SendSignalWithContext(context.Background(), sig)
}
// Suspend sends SIGSTOP to the process.
func (p *Process) Suspend() error {
return p.SuspendWithContext(context.Background())
}
// Resume sends SIGCONT to the process.
func (p *Process) Resume() error {
return p.ResumeWithContext(context.Background())
}
// Terminate sends SIGTERM to the process.
func (p *Process) Terminate() error {
return p.TerminateWithContext(context.Background())
}
// Kill sends SIGKILL to the process.
func (p *Process) Kill() error {
return p.KillWithContext(context.Background())
}
// Username returns a username of the process.
func (p *Process) Username() (string, error) {
return p.UsernameWithContext(context.Background())
}

View File

@ -0,0 +1,80 @@
// +build darwin freebsd openbsd
package process
import (
"bytes"
"context"
"encoding/binary"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/net"
)
type MemoryInfoExStat struct{}
type MemoryMapsStat struct{}
func (p *Process) TgidWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
return nil, common.ErrNotImplementedError
}
func parseKinfoProc(buf []byte) (KinfoProc, error) {
var k KinfoProc
br := bytes.NewReader(buf)
err := common.Read(br, binary.LittleEndian, &k)
return k, err
}

View File

@ -3,16 +3,13 @@
package process package process
import ( import (
"bytes"
"context" "context"
"encoding/binary"
"fmt" "fmt"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"unsafe"
"github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
@ -38,13 +35,6 @@ type _Ctype_struct___0 struct {
Pad uint64 Pad uint64
} }
// MemoryInfoExStat is different between OSes
type MemoryInfoExStat struct {
}
type MemoryMapsStat struct {
}
func pidsWithContext(ctx context.Context) ([]int32, error) { func pidsWithContext(ctx context.Context) ([]int32, error) {
var ret []int32 var ret []int32
@ -64,10 +54,6 @@ func pidsWithContext(ctx context.Context) ([]int32, error) {
return ret, nil return ret, nil
} }
func (p *Process) Ppid() (int32, error) {
return p.PpidWithContext(context.Background())
}
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
r, err := callPsWithContext(ctx, "ppid", p.Pid, false) r, err := callPsWithContext(ctx, "ppid", p.Pid, false)
if err != nil { if err != nil {
@ -81,9 +67,6 @@ func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
return int32(v), err return int32(v), err
} }
func (p *Process) Name() (string, error) {
return p.NameWithContext(context.Background())
}
func (p *Process) NameWithContext(ctx context.Context) (string, error) { func (p *Process) NameWithContext(ctx context.Context) (string, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -109,18 +92,6 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
return name, nil return name, nil
} }
func (p *Process) Tgid() (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Exe() (string, error) {
return p.ExeWithContext(context.Background())
}
// Cmdline returns the command line arguments of the process as a string with
// each argument separated by 0x20 ascii character.
func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
r, err := callPsWithContext(ctx, "command", p.Pid, false) r, err := callPsWithContext(ctx, "command", p.Pid, false)
@ -130,15 +101,11 @@ func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
return strings.Join(r[0], " "), err return strings.Join(r[0], " "), err
} }
// CmdlineSlice returns the command line arguments of the process as a slice with each // CmdlineSliceWithContext returns the command line arguments of the process as a slice with each
// element being an argument. Because of current deficiencies in the way that the command // element being an argument. Because of current deficiencies in the way that the command
// line arguments are found, single arguments that have spaces in the will actually be // line arguments are found, single arguments that have spaces in the will actually be
// reported as two separate items. In order to do something better CGO would be needed // reported as two separate items. In order to do something better CGO would be needed
// to use the native darwin functions. // to use the native darwin functions.
func (p *Process) CmdlineSlice() ([]string, error) {
return p.CmdlineSliceWithContext(context.Background())
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
r, err := callPsWithContext(ctx, "command", p.Pid, false) r, err := callPsWithContext(ctx, "command", p.Pid, false)
if err != nil { if err != nil {
@ -177,38 +144,23 @@ func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
start := time.Now().Add(-elapsed) start := time.Now().Add(-elapsed)
return start.Unix() * 1000, nil return start.Unix() * 1000, nil
} }
func (p *Process) Cwd() (string, error) {
return p.CwdWithContext(context.Background())
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Parent() (*Process, error) {
return p.ParentWithContext(context.Background())
}
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
rr, err := common.CallLsofWithContext(ctx, invoke, p.Pid, "-FR") out, err := common.CallLsofWithContext(ctx, invoke, p.Pid, "-FR")
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, r := range rr { for _, line := range out {
if strings.HasPrefix(r, "p") { // skip if process if len(line) >= 1 && line[0] == 'R' {
continue v, err := strconv.Atoi(line[1:])
}
l := string(r)
v, err := strconv.Atoi(strings.Replace(l, "R", "", 1))
if err != nil { if err != nil {
return nil, err return nil, err
} }
return NewProcess(int32(v)) return NewProcessWithContext(ctx, int32(v))
}
} }
return nil, fmt.Errorf("could not find parent line") return nil, fmt.Errorf("could not find parent line")
} }
func (p *Process) Status() (string, error) {
return p.StatusWithContext(context.Background())
}
func (p *Process) StatusWithContext(ctx context.Context) (string, error) { func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
r, err := callPsWithContext(ctx, "state", p.Pid, false) r, err := callPsWithContext(ctx, "state", p.Pid, false)
@ -219,10 +171,6 @@ func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
return r[0][0][0:1], err return r[0][0][0:1], err
} }
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details // see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
pid := p.Pid pid := p.Pid
@ -237,10 +185,6 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
return strings.IndexByte(string(out), '+') != -1, nil return strings.IndexByte(string(out), '+') != -1, nil
} }
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
if err != nil { if err != nil {
@ -252,9 +196,6 @@ func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
return []int32{userEffectiveUID}, nil return []int32{userEffectiveUID}, nil
} }
func (p *Process) Gids() ([]int32, error) {
return p.GidsWithContext(context.Background())
}
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -269,20 +210,18 @@ func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
} }
func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc() return nil, common.ErrNotImplementedError
if err != nil { // k, err := p.getKProc()
return nil, err // if err != nil {
} // return nil, err
// }
groups := make([]int32, k.Eproc.Ucred.Ngroups) // groups := make([]int32, k.Eproc.Ucred.Ngroups)
for i := int16(0); i < k.Eproc.Ucred.Ngroups; i++ { // for i := int16(0); i < k.Eproc.Ucred.Ngroups; i++ {
groups[i] = int32(k.Eproc.Ucred.Groups[i]) // groups[i] = int32(k.Eproc.Ucred.Groups[i])
} // }
return groups, nil // return groups, nil
}
func (p *Process) Terminal() (string, error) {
return p.TerminalWithContext(context.Background())
} }
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) { func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
@ -302,9 +241,6 @@ func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
return termmap[ttyNr], nil return termmap[ttyNr], nil
*/ */
} }
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) { func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -313,53 +249,10 @@ func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
} }
return int32(k.Proc.P_nice), nil return int32(k.Proc.P_nice), nil
} }
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())
}
func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Rlimit() ([]RlimitStat, error) {
return p.RlimitWithContext(context.Background())
}
func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) RlimitUsage(gatherUsed bool) ([]RlimitStat, error) {
return p.RlimitUsageWithContext(context.Background(), gatherUsed)
}
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.IOCountersWithContext(context.Background())
}
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) { func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return p.NumCtxSwitchesWithContext(context.Background())
}
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NumFDs() (int32, error) {
return p.NumFDsWithContext(context.Background())
}
func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) NumThreads() (int32, error) {
return p.NumThreadsWithContext(context.Background())
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
r, err := callPsWithContext(ctx, "utime,stime", p.Pid, true) r, err := callPsWithContext(ctx, "utime,stime", p.Pid, true)
@ -368,14 +261,6 @@ func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
} }
return int32(len(r)), nil return int32(len(r)), nil
} }
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
return p.ThreadsWithContext(context.Background())
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
ret := make(map[int32]*cpu.TimesStat)
return ret, common.ErrNotImplementedError
}
func convertCPUTimes(s string) (ret float64, err error) { func convertCPUTimes(s string) (ret float64, err error) {
var t int var t int
@ -422,9 +307,6 @@ func convertCPUTimes(s string) (ret float64, err error) {
t += h t += h
return float64(t) / ClockTicks, nil return float64(t) / ClockTicks, nil
} }
func (p *Process) Times() (*cpu.TimesStat, error) {
return p.TimesWithContext(context.Background())
}
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
r, err := callPsWithContext(ctx, "utime,stime", p.Pid, false) r, err := callPsWithContext(ctx, "utime,stime", p.Pid, false)
@ -449,16 +331,6 @@ func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error)
} }
return ret, nil return ret, nil
} }
func (p *Process) CPUAffinity() ([]int32, error) {
return p.CPUAffinityWithContext(context.Background())
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
r, err := callPsWithContext(ctx, "rss,vsize,pagein", p.Pid, false) r, err := callPsWithContext(ctx, "rss,vsize,pagein", p.Pid, false)
@ -486,25 +358,6 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e
return ret, nil return ret, nil
} }
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) PageFaults() (*PageFaultsStat, error) {
return p.PageFaultsWithContext(context.Background())
}
func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid) pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid)
@ -513,7 +366,7 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
} }
ret := make([]*Process, 0, len(pids)) ret := make([]*Process, 0, len(pids))
for _, pid := range pids { for _, pid := range pids {
np, err := NewProcess(pid) np, err := NewProcessWithContext(ctx, pid)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -522,50 +375,12 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
return ret, nil return ret, nil
} }
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
}
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) { func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
return net.ConnectionsPid("all", p.Pid) return net.ConnectionsPidWithContext(ctx, "all", p.Pid)
}
// Connections returns a slice of net.ConnectionStat used by the process at most `max`
func (p *Process) ConnectionsMax(max int) ([]net.ConnectionStat, error) {
return p.ConnectionsMaxWithContext(context.Background(), max)
} }
func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) { func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) {
return net.ConnectionsPidMax("all", p.Pid, max) return net.ConnectionsPidMaxWithContext(ctx, "all", p.Pid, max)
}
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
}
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
}
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
var ret []MemoryMapsStat
return &ret, common.ErrNotImplementedError
}
func Processes() ([]*Process, error) {
return ProcessesWithContext(context.Background())
} }
func ProcessesWithContext(ctx context.Context) ([]*Process, error) { func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
@ -577,7 +392,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
} }
for _, pid := range pids { for _, pid := range pids {
p, err := NewProcess(pid) p, err := NewProcessWithContext(ctx, pid)
if err != nil { if err != nil {
continue continue
} }
@ -587,39 +402,12 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
return out, nil return out, nil
} }
func parseKinfoProc(buf []byte) (KinfoProc, error) {
var k KinfoProc
br := bytes.NewReader(buf)
err := common.Read(br, binary.LittleEndian, &k)
if err != nil {
return k, err
}
return k, nil
}
// Returns a proc as defined here: // Returns a proc as defined here:
// http://unix.superglobalmegacorp.com/Net2/newsrc/sys/kinfo_proc.h.html // http://unix.superglobalmegacorp.com/Net2/newsrc/sys/kinfo_proc.h.html
func (p *Process) getKProc() (*KinfoProc, error) { func (p *Process) getKProc() (*KinfoProc, error) {
return p.getKProcWithContext(context.Background()) buf, err := unix.SysctlRaw("kern.proc.pid", int(p.Pid))
} if err != nil {
return nil, err
func (p *Process) getKProcWithContext(ctx context.Context) (*KinfoProc, error) {
mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid}
procK := KinfoProc{}
length := uint64(unsafe.Sizeof(procK))
buf := make([]byte, length)
_, _, syserr := unix.Syscall6(
unix.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) k, err := parseKinfoProc(buf)
if err != nil { if err != nil {

View File

@ -0,0 +1,205 @@
// +build darwin
// +build arm64
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs process/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 *Proc
Sess *Session
Pcred Upcred
Ucred Uucred
Vm Vmspace
Ppid int32
Pgid int32
Jobc int16
Tdev int32
Tpgid int32
Tsess *Session
Wmesg [8]int8
Xsize int32
Xrssize int16
Xccount int16
Xswrss int16
Flag int32
Login [12]int8
Spare [4]int32
Pad_cgo_0 [4]byte
}
type Proc struct{}
type Session struct{}
type ucred struct{}
type Uucred struct {
Ref int32
UID uint32
Ngroups int16
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
Dummy2 *int8
Dummy3 [5]int32
Dummy4 [3]*int8
}
type Sigacts struct{}
type ExternProc struct {
P_un [16]byte
P_vmspace *Vmspace
P_sigacts *Sigacts
P_flag int32
P_stat int8
P_pid int32
P_oppid int32
P_dupfd int32
User_stack *int8
Exit_thread *byte
P_debugger int32
Sigwait int32
P_estcpu uint32
P_cpticks int32
P_pctcpu uint32
P_wchan *byte
P_wmesg *int8
P_swtime uint32
P_slptime uint32
P_realtimer Itimerval
P_rtime Timeval
P_uticks uint64
P_sticks uint64
P_iticks uint64
P_traceflag int32
P_tracep *Vnode
P_siglist int32
P_textvp *Vnode
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
P_pgrp *Pgrp
P_addr *UserStruct
P_xstat uint16
P_acflag uint16
P_ru *Rusage
}
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{}
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
}

View File

@ -29,10 +29,6 @@ type MemoryInfoExStat struct {
} }
func pidsWithContext(ctx context.Context) ([]int32, error) { func pidsWithContext(ctx context.Context) ([]int32, error) {
return []int32{}, common.ErrNotImplementedError
}
func Processes() ([]*Process, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
@ -41,295 +37,168 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
} }
func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) { func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
pids, err := PidsWithContext(ctx) return false, common.ErrNotImplementedError
if err != nil {
return false, err
}
for _, i := range pids {
if i == pid {
return true, err
}
}
return false, err
}
func (p *Process) Ppid() (int32, error) {
return p.PpidWithContext(context.Background())
} }
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Name() (string, error) {
return p.NameWithContext(context.Background())
}
func (p *Process) NameWithContext(ctx context.Context) (string, error) { func (p *Process) NameWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Tgid() (int32, error) {
func (p *Process) TgidWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Exe() (string, error) {
return p.ExeWithContext(context.Background())
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) { func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) CmdlineSlice() ([]string, error) {
return p.CmdlineSliceWithContext(context.Background())
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
return []string{}, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Cwd() (string, error) {
return p.CwdWithContext(context.Background())
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) { func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Parent() (*Process, error) {
return p.ParentWithContext(context.Background())
}
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) Status() (string, error) {
return p.StatusWithContext(context.Background())
}
func (p *Process) StatusWithContext(ctx context.Context) (string, error) { func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
return false, common.ErrNotImplementedError return false, common.ErrNotImplementedError
} }
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
return []int32{}, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
}
func (p *Process) Gids() ([]int32, error) {
return p.GidsWithContext(context.Background())
} }
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
return []int32{}, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) {
return []int32{}, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
}
func (p *Process) Terminal() (string, error) {
return p.TerminalWithContext(context.Background())
} }
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) { func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) { func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())
}
func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) { func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Rlimit() ([]RlimitStat, error) {
return p.RlimitWithContext(context.Background())
}
func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) { func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) RlimitUsage(gatherUsed bool) ([]RlimitStat, error) {
return p.RlimitUsageWithContext(context.Background(), gatherUsed)
}
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) { func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.IOCountersWithContext(context.Background())
}
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) { func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return p.NumCtxSwitchesWithContext(context.Background())
}
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) { func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) NumFDs() (int32, error) {
return p.NumFDsWithContext(context.Background())
}
func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) { func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) NumThreads() (int32, error) {
return p.NumThreadsWithContext(context.Background())
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
return p.ThreadsWithContext(context.Background())
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) { func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) Times() (*cpu.TimesStat, error) {
return p.TimesWithContext(context.Background())
}
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) CPUAffinity() ([]int32, error) {
return p.CPUAffinityWithContext(context.Background())
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) { func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) { func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) PageFaults() (*PageFaultsStat, error) {
return p.PageFaultsWithContext(context.Background())
}
func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) { func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) { func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
return []OpenFilesStat{}, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
}
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
} }
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) { func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
return []net.ConnectionStat{}, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
}
func (p *Process) ConnectionsMax(max int) ([]net.ConnectionStat, error) {
return p.ConnectionsMaxWithContext(context.Background(), max)
} }
func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) { func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) {
return []net.ConnectionStat{}, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
}
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
} }
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) { func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
return []net.IOCountersStat{}, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
} }
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) { func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) SendSignal(sig syscall.Signal) error {
return p.SendSignalWithContext(context.Background(), sig)
}
func (p *Process) SendSignalWithContext(ctx context.Context, sig syscall.Signal) error { func (p *Process) SendSignalWithContext(ctx context.Context, sig syscall.Signal) error {
return common.ErrNotImplementedError return common.ErrNotImplementedError
} }
func (p *Process) Suspend() error {
return p.SuspendWithContext(context.Background())
}
func (p *Process) SuspendWithContext(ctx context.Context) error { func (p *Process) SuspendWithContext(ctx context.Context) error {
return common.ErrNotImplementedError return common.ErrNotImplementedError
} }
func (p *Process) Resume() error {
return p.ResumeWithContext(context.Background())
}
func (p *Process) ResumeWithContext(ctx context.Context) error { func (p *Process) ResumeWithContext(ctx context.Context) error {
return common.ErrNotImplementedError return common.ErrNotImplementedError
} }
func (p *Process) Terminate() error {
return p.TerminateWithContext(context.Background())
}
func (p *Process) TerminateWithContext(ctx context.Context) error { func (p *Process) TerminateWithContext(ctx context.Context) error {
return common.ErrNotImplementedError return common.ErrNotImplementedError
} }
func (p *Process) Kill() error {
return p.KillWithContext(context.Background())
}
func (p *Process) KillWithContext(ctx context.Context) error { func (p *Process) KillWithContext(ctx context.Context) error {
return common.ErrNotImplementedError return common.ErrNotImplementedError
} }
func (p *Process) Username() (string, error) {
return p.UsernameWithContext(context.Background())
}
func (p *Process) UsernameWithContext(ctx context.Context) (string, error) { func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError return "", common.ErrNotImplementedError

View File

@ -5,7 +5,6 @@ package process
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/binary"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strconv" "strconv"
@ -17,16 +16,9 @@ import (
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
// MemoryInfoExStat is different between OSes
type MemoryInfoExStat struct {
}
type MemoryMapsStat struct {
}
func pidsWithContext(ctx context.Context) ([]int32, error) { func pidsWithContext(ctx context.Context) ([]int32, error) {
var ret []int32 var ret []int32
procs, err := Processes() procs, err := ProcessesWithContext(ctx)
if err != nil { if err != nil {
return ret, nil return ret, nil
} }
@ -38,10 +30,6 @@ func pidsWithContext(ctx context.Context) ([]int32, error) {
return ret, nil return ret, nil
} }
func (p *Process) Ppid() (int32, error) {
return p.PpidWithContext(context.Background())
}
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
if err != nil { if err != nil {
@ -50,9 +38,6 @@ func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
return k.Ppid, nil return k.Ppid, nil
} }
func (p *Process) Name() (string, error) {
return p.NameWithContext(context.Background())
}
func (p *Process) NameWithContext(ctx context.Context) (string, error) { func (p *Process) NameWithContext(ctx context.Context) (string, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -78,21 +63,11 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
return name, nil return name, nil
} }
func (p *Process) Tgid() (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Exe() (string, error) {
return p.ExeWithContext(context.Background())
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) { func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid} mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid}
buf, _, err := common.CallSyscall(mib) buf, _, err := common.CallSyscall(mib)
@ -109,10 +84,6 @@ func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
return strings.Join(ret, " "), nil return strings.Join(ret, " "), nil
} }
func (p *Process) CmdlineSlice() ([]string, error) {
return p.CmdlineSliceWithContext(context.Background())
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid} mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid}
buf, _, err := common.CallSyscall(mib) buf, _, err := common.CallSyscall(mib)
@ -137,22 +108,9 @@ func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error)
func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Cwd() (string, error) {
return p.CwdWithContext(context.Background())
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Parent() (*Process, error) {
return p.ParentWithContext(context.Background())
}
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
return p, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
}
func (p *Process) Status() (string, error) {
return p.StatusWithContext(context.Background())
} }
func (p *Process) StatusWithContext(ctx context.Context) (string, error) { func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
@ -181,10 +139,6 @@ func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
return s, nil return s, nil
} }
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details // see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
pid := p.Pid pid := p.Pid
@ -199,10 +153,6 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
return strings.IndexByte(string(out), '+') != -1, nil return strings.IndexByte(string(out), '+') != -1, nil
} }
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
if err != nil { if err != nil {
@ -215,9 +165,6 @@ func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
return uids, nil return uids, nil
} }
func (p *Process) Gids() ([]int32, error) {
return p.GidsWithContext(context.Background())
}
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -244,9 +191,6 @@ func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) {
return groups, nil return groups, nil
} }
func (p *Process) Terminal() (string, error) {
return p.TerminalWithContext(context.Background())
}
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) { func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -263,9 +207,6 @@ func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
return termmap[ttyNr], nil return termmap[ttyNr], nil
} }
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) { func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -274,32 +215,6 @@ func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
} }
return int32(k.Nice), nil return int32(k.Nice), nil
} }
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())
}
func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Rlimit() ([]RlimitStat, error) {
return p.RlimitWithContext(context.Background())
}
func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) RlimitUsage(gatherUsed bool) ([]RlimitStat, error) {
return p.RlimitUsageWithContext(context.Background(), gatherUsed)
}
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.IOCountersWithContext(context.Background())
}
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) { func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -311,23 +226,6 @@ func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, e
WriteCount: uint64(k.Rusage.Oublock), WriteCount: uint64(k.Rusage.Oublock),
}, nil }, nil
} }
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return p.NumCtxSwitchesWithContext(context.Background())
}
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NumFDs() (int32, error) {
return p.NumFDsWithContext(context.Background())
}
func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) NumThreads() (int32, error) {
return p.NumThreadsWithContext(context.Background())
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -337,17 +235,6 @@ func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
return k.Numthreads, nil return k.Numthreads, nil
} }
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
return p.ThreadsWithContext(context.Background())
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
ret := make(map[int32]*cpu.TimesStat)
return ret, common.ErrNotImplementedError
}
func (p *Process) Times() (*cpu.TimesStat, error) {
return p.TimesWithContext(context.Background())
}
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -360,16 +247,6 @@ func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error)
System: float64(k.Rusage.Stime.Sec) + float64(k.Rusage.Stime.Usec)/1000000, System: float64(k.Rusage.Stime.Sec) + float64(k.Rusage.Stime.Usec)/1000000,
}, nil }, nil
} }
func (p *Process) CPUAffinity() ([]int32, error) {
return p.CPUAffinityWithContext(context.Background())
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -387,25 +264,6 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e
VMS: uint64(k.Size), VMS: uint64(k.Size),
}, nil }, nil
} }
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) PageFaults() (*PageFaultsStat, error) {
return p.PageFaultsWithContext(context.Background())
}
func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid) pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid)
@ -414,7 +272,7 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
} }
ret := make([]*Process, 0, len(pids)) ret := make([]*Process, 0, len(pids))
for _, pid := range pids { for _, pid := range pids {
np, err := NewProcess(pid) np, err := NewProcessWithContext(ctx, pid)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -423,52 +281,14 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
return ret, nil return ret, nil
} }
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
}
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) { func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
// Connections returns a slice of net.ConnectionStat used by the process at most `max`
func (p *Process) ConnectionsMax(max int) ([]net.ConnectionStat, error) {
return p.ConnectionsMaxWithContext(context.Background(), max)
}
func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) { func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) {
return []net.ConnectionStat{}, common.ErrNotImplementedError
}
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
}
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
}
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
var ret []MemoryMapsStat
return &ret, common.ErrNotImplementedError
}
func Processes() ([]*Process, error) {
return ProcessesWithContext(context.Background())
}
func ProcessesWithContext(ctx context.Context) ([]*Process, error) { func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
results := []*Process{} results := []*Process{}
@ -488,7 +308,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
if err != nil { if err != nil {
continue continue
} }
p, err := NewProcess(int32(k.Pid)) p, err := NewProcessWithContext(ctx, int32(k.Pid))
if err != nil { if err != nil {
continue continue
} }
@ -499,18 +319,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
return results, nil return results, nil
} }
func parseKinfoProc(buf []byte) (KinfoProc, error) {
var k KinfoProc
br := bytes.NewReader(buf)
err := common.Read(br, binary.LittleEndian, &k)
return k, err
}
func (p *Process) getKProc() (*KinfoProc, error) { func (p *Process) getKProc() (*KinfoProc, error) {
return p.getKProcWithContext(context.Background())
}
func (p *Process) getKProcWithContext(ctx context.Context) (*KinfoProc, error) {
mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid} mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid}
buf, length, err := common.CallSyscall(mib) buf, length, err := common.CallSyscall(mib)

View File

@ -64,11 +64,6 @@ func (m MemoryMapsStat) String() string {
return string(s) return string(s)
} }
// Ppid returns Parent Process ID of the process.
func (p *Process) Ppid() (int32, error) {
return p.PpidWithContext(context.Background())
}
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
_, ppid, _, _, _, _, _, err := p.fillFromStatWithContext(ctx) _, ppid, _, _, _, _, _, err := p.fillFromStatWithContext(ctx)
if err != nil { if err != nil {
@ -77,11 +72,6 @@ func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
return ppid, nil return ppid, nil
} }
// Name returns name of the process.
func (p *Process) Name() (string, error) {
return p.NameWithContext(context.Background())
}
func (p *Process) NameWithContext(ctx context.Context) (string, error) { func (p *Process) NameWithContext(ctx context.Context) (string, error) {
if p.name == "" { if p.name == "" {
if err := p.fillFromStatusWithContext(ctx); err != nil { if err := p.fillFromStatusWithContext(ctx); err != nil {
@ -91,41 +81,23 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
return p.name, nil return p.name, nil
} }
// Tgid returns tgid, a Linux-synonym for user-space Pid func (p *Process) TgidWithContext(ctx context.Context) (int32, error) {
func (p *Process) Tgid() (int32, error) {
if p.tgid == 0 { if p.tgid == 0 {
if err := p.fillFromStatusWithContext(context.Background()); err != nil { if err := p.fillFromStatusWithContext(ctx); err != nil {
return 0, err return 0, err
} }
} }
return p.tgid, nil return p.tgid, nil
} }
// Exe returns executable path of the process.
func (p *Process) Exe() (string, error) {
return p.ExeWithContext(context.Background())
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) { func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
return p.fillFromExeWithContext(ctx) return p.fillFromExeWithContext(ctx)
} }
// Cmdline returns the command line arguments of the process as a string with
// each argument separated by 0x20 ascii character.
func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
return p.fillFromCmdlineWithContext(ctx) return p.fillFromCmdlineWithContext(ctx)
} }
// CmdlineSlice returns the command line arguments of the process as a slice with each
// element being an argument.
func (p *Process) CmdlineSlice() ([]string, error) {
return p.CmdlineSliceWithContext(context.Background())
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
return p.fillSliceFromCmdlineWithContext(ctx) return p.fillSliceFromCmdlineWithContext(ctx)
} }
@ -138,20 +110,10 @@ func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
return createTime, nil return createTime, nil
} }
// Cwd returns current working directory of the process.
func (p *Process) Cwd() (string, error) {
return p.CwdWithContext(context.Background())
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) { func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return p.fillFromCwdWithContext(ctx) return p.fillFromCwdWithContext(ctx)
} }
// Parent returns parent Process of the process.
func (p *Process) Parent() (*Process, error) {
return p.ParentWithContext(context.Background())
}
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
err := p.fillFromStatusWithContext(ctx) err := p.fillFromStatusWithContext(ctx)
if err != nil { if err != nil {
@ -160,16 +122,7 @@ func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
if p.parent == 0 { if p.parent == 0 {
return nil, fmt.Errorf("wrong number of parents") return nil, fmt.Errorf("wrong number of parents")
} }
return NewProcess(p.parent) return NewProcessWithContext(ctx, p.parent)
}
// Status returns the process status.
// Return value could be one of these.
// R: Running S: Sleep T: Stop I: Idle
// Z: Zombie W: Wait L: Lock
// The character is same within all supported platforms.
func (p *Process) Status() (string, error) {
return p.StatusWithContext(context.Background())
} }
func (p *Process) StatusWithContext(ctx context.Context) (string, error) { func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
@ -180,11 +133,6 @@ func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
return p.status, nil return p.status, nil
} }
// Foreground returns true if the process is in foreground, false otherwise.
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details // see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
pid := p.Pid pid := p.Pid
@ -202,11 +150,6 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
return pgid == tpgid, nil return pgid == tpgid, nil
} }
// Uids returns user ids of the process as a slice of the int
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
err := p.fillFromStatusWithContext(ctx) err := p.fillFromStatusWithContext(ctx)
if err != nil { if err != nil {
@ -215,11 +158,6 @@ func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
return p.uids, nil return p.uids, nil
} }
// Gids returns group ids of the process as a slice of the int
func (p *Process) Gids() ([]int32, error) {
return p.GidsWithContext(context.Background())
}
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
err := p.fillFromStatusWithContext(ctx) err := p.fillFromStatusWithContext(ctx)
if err != nil { if err != nil {
@ -236,11 +174,6 @@ func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) {
return p.groups, nil return p.groups, nil
} }
// Terminal returns a terminal which is associated with the process.
func (p *Process) Terminal() (string, error) {
return p.TerminalWithContext(context.Background())
}
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) { func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
t, _, _, _, _, _, _, err := p.fillFromStatWithContext(ctx) t, _, _, _, _, _, _, err := p.fillFromStatWithContext(ctx)
if err != nil { if err != nil {
@ -254,12 +187,6 @@ func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
return terminal, nil return terminal, nil
} }
// Nice returns a nice value (priority).
// Notice: gopsutil can not set nice value.
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) { func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
_, _, _, _, _, nice, _, err := p.fillFromStatWithContext(ctx) _, _, _, _, _, nice, _, err := p.fillFromStatWithContext(ctx)
if err != nil { if err != nil {
@ -268,29 +195,12 @@ func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
return nice, nil return nice, nil
} }
// IOnice returns process I/O nice value (priority).
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())
}
func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) { func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
// Rlimit returns Resource Limits.
func (p *Process) Rlimit() ([]RlimitStat, error) {
return p.RlimitWithContext(context.Background())
}
func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) { func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
return p.RlimitUsage(false) return p.RlimitUsageWithContext(ctx, false)
}
// RlimitUsage returns Resource Limits.
// If gatherUsed is true, the currently used value will be gathered and added
// to the resulting RlimitStat.
func (p *Process) RlimitUsage(gatherUsed bool) ([]RlimitStat, error) {
return p.RlimitUsageWithContext(context.Background(), gatherUsed)
} }
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) { func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
@ -311,7 +221,7 @@ func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) (
rs := &rlimits[i] rs := &rlimits[i]
switch rs.Resource { switch rs.Resource {
case RLIMIT_CPU: case RLIMIT_CPU:
times, err := p.Times() times, err := p.TimesWithContext(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -323,7 +233,7 @@ func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) (
case RLIMIT_RSS: case RLIMIT_RSS:
rs.Used = uint64(p.memInfo.RSS) rs.Used = uint64(p.memInfo.RSS)
case RLIMIT_NOFILE: case RLIMIT_NOFILE:
n, err := p.NumFDs() n, err := p.NumFDsWithContext(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -348,20 +258,10 @@ func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) (
return rlimits, err return rlimits, err
} }
// IOCounters returns IO Counters.
func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.IOCountersWithContext(context.Background())
}
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) { func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
return p.fillFromIOWithContext(ctx) return p.fillFromIOWithContext(ctx)
} }
// NumCtxSwitches returns the number of the context switches of the process.
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return p.NumCtxSwitchesWithContext(context.Background())
}
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) { func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
err := p.fillFromStatusWithContext(ctx) err := p.fillFromStatusWithContext(ctx)
if err != nil { if err != nil {
@ -370,21 +270,11 @@ func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitche
return p.numCtxSwitches, nil return p.numCtxSwitches, nil
} }
// NumFDs returns the number of File Descriptors used by the process.
func (p *Process) NumFDs() (int32, error) {
return p.NumFDsWithContext(context.Background())
}
func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) { func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
_, fnames, err := p.fillFromfdListWithContext(ctx) _, fnames, err := p.fillFromfdListWithContext(ctx)
return int32(len(fnames)), err return int32(len(fnames)), err
} }
// NumThreads returns the number of threads used by the process.
func (p *Process) NumThreads() (int32, error) {
return p.NumThreadsWithContext(context.Background())
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
err := p.fillFromStatusWithContext(ctx) err := p.fillFromStatusWithContext(ctx)
if err != nil { if err != nil {
@ -393,10 +283,6 @@ func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
return p.numThreads, nil return p.numThreads, nil
} }
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
return p.ThreadsWithContext(context.Background())
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) { func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
ret := make(map[int32]*cpu.TimesStat) ret := make(map[int32]*cpu.TimesStat)
taskPath := common.HostProc(strconv.Itoa(int(p.Pid)), "task") taskPath := common.HostProc(strconv.Itoa(int(p.Pid)), "task")
@ -417,11 +303,6 @@ func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesS
return ret, nil return ret, nil
} }
// Times returns CPU times of the process.
func (p *Process) Times() (*cpu.TimesStat, error) {
return p.TimesWithContext(context.Background())
}
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
_, _, cpuTimes, _, _, _, _, err := p.fillFromStatWithContext(ctx) _, _, cpuTimes, _, _, _, _, err := p.fillFromStatWithContext(ctx)
if err != nil { if err != nil {
@ -430,22 +311,10 @@ func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error)
return cpuTimes, nil return cpuTimes, nil
} }
// CPUAffinity returns CPU affinity of the process.
//
// Notice: Not implemented yet.
func (p *Process) CPUAffinity() ([]int32, error) {
return p.CPUAffinityWithContext(context.Background())
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) { func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
// MemoryInfo returns platform in-dependend memory information, such as RSS, VMS and Swap
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
meminfo, _, err := p.fillFromStatmWithContext(ctx) meminfo, _, err := p.fillFromStatmWithContext(ctx)
if err != nil { if err != nil {
@ -454,11 +323,6 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e
return meminfo, nil return meminfo, nil
} }
// MemoryInfoEx returns platform dependend memory information.
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) { func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
_, memInfoEx, err := p.fillFromStatmWithContext(ctx) _, memInfoEx, err := p.fillFromStatmWithContext(ctx)
if err != nil { if err != nil {
@ -467,11 +331,6 @@ func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExSta
return memInfoEx, nil return memInfoEx, nil
} }
// PageFaultsInfo returns the process's page fault counters
func (p *Process) PageFaults() (*PageFaultsStat, error) {
return p.PageFaultsWithContext(context.Background())
}
func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) { func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) {
_, _, _, _, _, _, pageFaults, err := p.fillFromStatWithContext(ctx) _, _, _, _, _, _, pageFaults, err := p.fillFromStatWithContext(ctx)
if err != nil { if err != nil {
@ -481,11 +340,6 @@ func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, e
} }
// Children returns a slice of Process of the process.
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid) pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid)
if err != nil { if err != nil {
@ -496,7 +350,7 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
} }
ret := make([]*Process, 0, len(pids)) ret := make([]*Process, 0, len(pids))
for _, pid := range pids { for _, pid := range pids {
np, err := NewProcess(pid) np, err := NewProcessWithContext(ctx, pid)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -505,12 +359,6 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
return ret, nil return ret, nil
} }
// OpenFiles returns a slice of OpenFilesStat opend by the process.
// OpenFilesStat includes a file path and file descriptor.
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) { func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
_, ofs, err := p.fillFromfdWithContext(ctx) _, ofs, err := p.fillFromfdWithContext(ctx)
if err != nil { if err != nil {
@ -524,38 +372,17 @@ func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, er
return ret, nil return ret, nil
} }
// Connections returns a slice of net.ConnectionStat used by the process.
// This returns all kind of the connection. This measn TCP, UDP or UNIX.
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
}
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) { func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
return net.ConnectionsPid("all", p.Pid) return net.ConnectionsPidWithContext(ctx, "all", p.Pid)
}
// Connections returns a slice of net.ConnectionStat used by the process at most `max`
func (p *Process) ConnectionsMax(max int) ([]net.ConnectionStat, error) {
return p.ConnectionsMaxWithContext(context.Background(), max)
} }
func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) { func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) {
return net.ConnectionsPidMax("all", p.Pid, max) return net.ConnectionsPidMaxWithContext(ctx, "all", p.Pid, max)
}
// NetIOCounters returns NetIOCounters of the process.
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
} }
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) { func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
filename := common.HostProc(strconv.Itoa(int(p.Pid)), "net/dev") filename := common.HostProc(strconv.Itoa(int(p.Pid)), "net/dev")
return net.IOCountersByFile(pernic, filename) return net.IOCountersByFileWithContext(ctx, pernic, filename)
}
// MemoryMaps get memory maps from /proc/(pid)/smaps
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
} }
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) { func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
@ -1249,12 +1076,6 @@ func pidsWithContext(ctx context.Context) ([]int32, error) {
return readPidsFromDir(common.HostProc()) return readPidsFromDir(common.HostProc())
} }
// Process returns a slice of pointers to Process structs for all
// currently running processes.
func Processes() ([]*Process, error) {
return ProcessesWithContext(context.Background())
}
func ProcessesWithContext(ctx context.Context) ([]*Process, error) { func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
out := []*Process{} out := []*Process{}
@ -1264,7 +1085,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
} }
for _, pid := range pids { for _, pid := range pids {
p, err := NewProcess(pid) p, err := NewProcessWithContext(ctx, pid)
if err != nil { if err != nil {
continue continue
} }

View File

@ -4,9 +4,7 @@ package process
import ( import (
"C" "C"
"bytes"
"context" "context"
"encoding/binary"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strconv" "strconv"
@ -20,16 +18,9 @@ import (
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
// MemoryInfoExStat is different between OSes
type MemoryInfoExStat struct {
}
type MemoryMapsStat struct {
}
func pidsWithContext(ctx context.Context) ([]int32, error) { func pidsWithContext(ctx context.Context) ([]int32, error) {
var ret []int32 var ret []int32
procs, err := Processes() procs, err := ProcessesWithContext(ctx)
if err != nil { if err != nil {
return ret, nil return ret, nil
} }
@ -41,10 +32,6 @@ func pidsWithContext(ctx context.Context) ([]int32, error) {
return ret, nil return ret, nil
} }
func (p *Process) Ppid() (int32, error) {
return p.PpidWithContext(context.Background())
}
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
if err != nil { if err != nil {
@ -53,9 +40,6 @@ func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
return k.Ppid, nil return k.Ppid, nil
} }
func (p *Process) Name() (string, error) {
return p.NameWithContext(context.Background())
}
func (p *Process) NameWithContext(ctx context.Context) (string, error) { func (p *Process) NameWithContext(ctx context.Context) (string, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -81,21 +65,11 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
return name, nil return name, nil
} }
func (p *Process) Tgid() (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Exe() (string, error) {
return p.ExeWithContext(context.Background())
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) { func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) CmdlineSlice() ([]string, error) {
return p.CmdlineSliceWithContext(context.Background())
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
mib := []int32{CTLKern, KernProcArgs, p.Pid, KernProcArgv} mib := []int32{CTLKern, KernProcArgs, p.Pid, KernProcArgv}
buf, _, err := common.CallSyscall(mib) buf, _, err := common.CallSyscall(mib)
@ -119,12 +93,8 @@ func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error)
return strParts, nil return strParts, nil
} }
func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
argv, err := p.CmdlineSlice() argv, err := p.CmdlineSliceWithContext(ctx)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -134,22 +104,9 @@ func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Cwd() (string, error) {
return p.CwdWithContext(context.Background())
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Parent() (*Process, error) {
return p.ParentWithContext(context.Background())
}
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
return p, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
}
func (p *Process) Status() (string, error) {
return p.StatusWithContext(context.Background())
} }
func (p *Process) StatusWithContext(ctx context.Context) (string, error) { func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
@ -173,9 +130,6 @@ func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
return s, nil return s, nil
} }
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details // see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
@ -190,9 +144,6 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
} }
return strings.IndexByte(string(out), '+') != -1, nil return strings.IndexByte(string(out), '+') != -1, nil
} }
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -206,9 +157,6 @@ func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
return uids, nil return uids, nil
} }
func (p *Process) Gids() ([]int32, error) {
return p.GidsWithContext(context.Background())
}
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -221,16 +169,19 @@ func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
return gids, nil return gids, nil
} }
func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return k.Groups, nil groups := make([]int32, k.Ngroups)
} for i := int16(0); i < k.Ngroups; i++ {
func (p *Process) Terminal() (string, error) { groups[i] = int32(k.Groups[i])
return p.TerminalWithContext(context.Background()) }
return groups, nil
} }
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) { func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
@ -248,9 +199,6 @@ func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
return termmap[ttyNr], nil return termmap[ttyNr], nil
} }
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) { func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -259,32 +207,6 @@ func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
} }
return int32(k.Nice), nil return int32(k.Nice), nil
} }
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())
}
func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Rlimit() ([]RlimitStat, error) {
return p.RlimitWithContext(context.Background())
}
func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) RlimitUsage(gatherUsed bool) ([]RlimitStat, error) {
return p.RlimitUsageWithContext(context.Background(), gatherUsed)
}
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.IOCountersWithContext(context.Background())
}
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) { func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -296,39 +218,11 @@ func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, e
WriteCount: uint64(k.Uru_oublock), WriteCount: uint64(k.Uru_oublock),
}, nil }, nil
} }
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return p.NumCtxSwitchesWithContext(context.Background())
}
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NumFDs() (int32, error) {
return p.NumFDsWithContext(context.Background())
}
func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) NumThreads() (int32, error) {
return p.NumThreadsWithContext(context.Background())
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
/* not supported, just return 1 */ /* not supported, just return 1 */
return 1, nil return 1, nil
} }
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
return p.ThreadsWithContext(context.Background())
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
ret := make(map[int32]*cpu.TimesStat)
return ret, common.ErrNotImplementedError
}
func (p *Process) Times() (*cpu.TimesStat, error) {
return p.TimesWithContext(context.Background())
}
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
k, err := p.getKProc() k, err := p.getKProc()
@ -341,23 +235,13 @@ func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error)
System: float64(k.Ustime_sec) + float64(k.Ustime_usec)/1000000, System: float64(k.Ustime_sec) + float64(k.Ustime_usec)/1000000,
}, nil }, nil
} }
func (p *Process) CPUAffinity() ([]int32, error) {
return p.CPUAffinityWithContext(context.Background())
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
k, err := p.getKProc() k, err := p.getKProc()
if err != nil { if err != nil {
return nil, err return nil, err
} }
pageSize, err := mem.GetPageSize() pageSize, err := mem.GetPageSizeWithContext(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -368,25 +252,6 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e
uint64(k.Vm_ssize), uint64(k.Vm_ssize),
}, nil }, nil
} }
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) PageFaults() (*PageFaultsStat, error) {
return p.PageFaultsWithContext(context.Background())
}
func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid) pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid)
@ -395,7 +260,7 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
} }
ret := make([]*Process, 0, len(pids)) ret := make([]*Process, 0, len(pids))
for _, pid := range pids { for _, pid := range pids {
np, err := NewProcess(pid) np, err := NewProcessWithContext(ctx, pid)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -404,55 +269,18 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
return ret, nil return ret, nil
} }
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
}
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) { func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) ConnectionsMax(max int) ([]net.ConnectionStat, error) {
return p.ConnectionsMaxWithContext(context.Background(), max)
}
func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) { func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) {
return []net.ConnectionStat{}, common.ErrNotImplementedError
}
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
}
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
}
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
var ret []MemoryMapsStat
return &ret, common.ErrNotImplementedError
}
func Processes() ([]*Process, error) {
return ProcessesWithContext(context.Background())
}
func ProcessesWithContext(ctx context.Context) ([]*Process, error) { func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
results := []*Process{} results := []*Process{}
buf, length, err := CallKernProcSyscall(KernProcAll, 0) buf, length, err := callKernProcSyscall(KernProcAll, 0)
if err != nil { if err != nil {
return results, err return results, err
@ -468,7 +296,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
if err != nil { if err != nil {
continue continue
} }
p, err := NewProcess(int32(k.Pid)) p, err := NewProcessWithContext(ctx, int32(k.Pid))
if err != nil { if err != nil {
continue continue
} }
@ -479,19 +307,8 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
return results, nil return results, nil
} }
func parseKinfoProc(buf []byte) (KinfoProc, error) {
var k KinfoProc
br := bytes.NewReader(buf)
err := common.Read(br, binary.LittleEndian, &k)
return k, err
}
func (p *Process) getKProc() (*KinfoProc, error) { func (p *Process) getKProc() (*KinfoProc, error) {
return p.getKProcWithContext(context.Background()) buf, length, err := callKernProcSyscall(KernProcPID, p.Pid)
}
func (p *Process) getKProcWithContext(ctx context.Context) (*KinfoProc, error) {
buf, length, err := CallKernProcSyscall(KernProcPID, p.Pid)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -506,11 +323,7 @@ func (p *Process) getKProcWithContext(ctx context.Context) (*KinfoProc, error) {
return &k, nil return &k, nil
} }
func CallKernProcSyscall(op int32, arg int32) ([]byte, uint64, error) { func callKernProcSyscall(op int32, arg int32) ([]byte, uint64, error) {
return CallKernProcSyscallWithContext(context.Background(), op, arg)
}
func CallKernProcSyscallWithContext(ctx context.Context, op int32, arg int32) ([]byte, uint64, error) {
mib := []int32{CTLKern, KernProc, op, arg, sizeOfKinfoProc, 0} mib := []int32{CTLKern, KernProc, op, arg, sizeOfKinfoProc, 0}
mibptr := unsafe.Pointer(&mib[0]) mibptr := unsafe.Pointer(&mib[0])
miblen := uint64(len(mib)) miblen := uint64(len(mib))

View File

@ -0,0 +1,201 @@
// +build openbsd
// +build 386
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs process/types_openbsd.go
package process
const (
CTLKern = 1
KernProc = 66
KernProcAll = 0
KernProcPID = 1
KernProcProc = 8
KernProcPathname = 12
KernProcArgs = 55
KernProcArgv = 1
KernProcEnv = 3
)
const (
ArgMax = 256 * 1024
)
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x4
sizeofLongLong = 0x8
)
const (
sizeOfKinfoVmentry = 0x38
sizeOfKinfoProc = 0x264
)
const (
SIDL = 1
SRUN = 2
SSLEEP = 3
SSTOP = 4
SZOMB = 5
SDEAD = 6
SONPROC = 7
)
type (
_C_short int16
_C_int int32
_C_long int32
_C_long_long int64
)
type Timespec struct {
Sec int64
Nsec int32
}
type Timeval struct {
Sec int64
Usec int32
}
type Rusage struct {
Utime Timeval
Stime Timeval
Maxrss int32
Ixrss int32
Idrss int32
Isrss int32
Minflt int32
Majflt int32
Nswap int32
Inblock int32
Oublock int32
Msgsnd int32
Msgrcv int32
Nsignals int32
Nvcsw int32
Nivcsw int32
}
type Rlimit struct {
Cur uint64
Max uint64
}
type KinfoProc struct {
Forw uint64
Back uint64
Paddr uint64
Addr uint64
Fd uint64
Stats uint64
Limit uint64
Vmspace uint64
Sigacts uint64
Sess uint64
Tsess uint64
Ru uint64
Eflag int32
Exitsig int32
Flag int32
Pid int32
Ppid int32
Sid int32
X_pgid int32
Tpgid int32
Uid uint32
Ruid uint32
Gid uint32
Rgid uint32
Groups [16]uint32
Ngroups int16
Jobc int16
Tdev uint32
Estcpu uint32
Rtime_sec uint32
Rtime_usec uint32
Cpticks int32
Pctcpu uint32
Swtime uint32
Slptime uint32
Schedflags int32
Uticks uint64
Sticks uint64
Iticks uint64
Tracep uint64
Traceflag int32
Holdcnt int32
Siglist int32
Sigmask uint32
Sigignore uint32
Sigcatch uint32
Stat int8
Priority uint8
Usrpri uint8
Nice uint8
Xstat uint16
Acflag uint16
Comm [24]int8
Wmesg [8]int8
Wchan uint64
Login [32]int8
Vm_rssize int32
Vm_tsize int32
Vm_dsize int32
Vm_ssize int32
Uvalid int64
Ustart_sec uint64
Ustart_usec uint32
Uutime_sec uint32
Uutime_usec uint32
Ustime_sec uint32
Ustime_usec uint32
Uru_maxrss uint64
Uru_ixrss uint64
Uru_idrss uint64
Uru_isrss uint64
Uru_minflt uint64
Uru_majflt uint64
Uru_nswap uint64
Uru_inblock uint64
Uru_oublock uint64
Uru_msgsnd uint64
Uru_msgrcv uint64
Uru_nsignals uint64
Uru_nvcsw uint64
Uru_nivcsw uint64
Uctime_sec uint32
Uctime_usec uint32
Psflags int32
Spare int32
Svuid uint32
Svgid uint32
Emul [8]int8
Rlim_rss_cur uint64
Cpuid uint64
Vm_map_size uint64
Tid int32
Rtableid uint32
}
type Priority struct{}
type KinfoVmentry struct {
Start uint32
End uint32
Guard uint32
Fspace uint32
Fspace_augment uint32
Offset uint64
Wired_count int32
Etype int32
Protection int32
Max_protection int32
Advice int32
Inheritance int32
Flags uint8
Pad_cgo_0 [3]byte
}

View File

@ -114,12 +114,6 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
return false, err return false, err
} }
// SendSignal sends a unix.Signal to the process.
// Currently, SIGSTOP, SIGCONT, SIGTERM and SIGKILL are supported.
func (p *Process) SendSignal(sig syscall.Signal) error {
return p.SendSignalWithContext(context.Background(), sig)
}
func (p *Process) SendSignalWithContext(ctx context.Context, sig syscall.Signal) error { func (p *Process) SendSignalWithContext(ctx context.Context, sig syscall.Signal) error {
process, err := os.FindProcess(int(p.Pid)) process, err := os.FindProcess(int(p.Pid))
if err != nil { if err != nil {
@ -134,49 +128,24 @@ func (p *Process) SendSignalWithContext(ctx context.Context, sig syscall.Signal)
return nil return nil
} }
// Suspend sends SIGSTOP to the process.
func (p *Process) Suspend() error {
return p.SuspendWithContext(context.Background())
}
func (p *Process) SuspendWithContext(ctx context.Context) error { func (p *Process) SuspendWithContext(ctx context.Context) error {
return p.SendSignal(unix.SIGSTOP) return p.SendSignalWithContext(ctx, unix.SIGSTOP)
}
// Resume sends SIGCONT to the process.
func (p *Process) Resume() error {
return p.ResumeWithContext(context.Background())
} }
func (p *Process) ResumeWithContext(ctx context.Context) error { func (p *Process) ResumeWithContext(ctx context.Context) error {
return p.SendSignal(unix.SIGCONT) return p.SendSignalWithContext(ctx, unix.SIGCONT)
}
// Terminate sends SIGTERM to the process.
func (p *Process) Terminate() error {
return p.TerminateWithContext(context.Background())
} }
func (p *Process) TerminateWithContext(ctx context.Context) error { func (p *Process) TerminateWithContext(ctx context.Context) error {
return p.SendSignal(unix.SIGTERM) return p.SendSignalWithContext(ctx, unix.SIGTERM)
}
// Kill sends SIGKILL to the process.
func (p *Process) Kill() error {
return p.KillWithContext(context.Background())
} }
func (p *Process) KillWithContext(ctx context.Context) error { func (p *Process) KillWithContext(ctx context.Context) error {
return p.SendSignal(unix.SIGKILL) return p.SendSignalWithContext(ctx, unix.SIGKILL)
}
// Username returns a username of the process.
func (p *Process) Username() (string, error) {
return p.UsernameWithContext(context.Background())
} }
func (p *Process) UsernameWithContext(ctx context.Context) (string, error) { func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
uids, err := p.Uids() uids, err := p.UidsWithContext(ctx)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -235,38 +235,43 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
return exitCode == STILL_ACTIVE, err return exitCode == STILL_ACTIVE, err
} }
func (p *Process) Ppid() (int32, error) {
return p.PpidWithContext(context.Background())
}
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
// if cached already, return from cache
cachedPpid := p.getPpid()
if cachedPpid != 0 {
return cachedPpid, nil
}
ppid, _, _, err := getFromSnapProcess(p.Pid) ppid, _, _, err := getFromSnapProcess(p.Pid)
if err != nil { if err != nil {
return 0, err return 0, err
} }
// no errors and not cached already, so cache it
p.setPpid(ppid)
return ppid, nil return ppid, nil
} }
func (p *Process) Name() (string, error) {
return p.NameWithContext(context.Background())
}
func (p *Process) NameWithContext(ctx context.Context) (string, error) { func (p *Process) NameWithContext(ctx context.Context) (string, error) {
_, _, name, err := getFromSnapProcess(p.Pid) ppid, _, name, err := getFromSnapProcess(p.Pid)
if err != nil { if err != nil {
return "", fmt.Errorf("could not get Name: %s", err) return "", fmt.Errorf("could not get Name: %s", err)
} }
// if no errors and not cached already, cache ppid
p.parent = ppid
if 0 == p.getPpid() {
p.setPpid(ppid)
}
return name, nil return name, nil
} }
func (p *Process) Tgid() (int32, error) { func (p *Process) TgidWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Exe() (string, error) {
return p.ExeWithContext(context.Background())
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) { func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(p.Pid)) c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(p.Pid))
if err != nil { if err != nil {
@ -294,10 +299,6 @@ func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
return common.ConvertDOSPath(windows.UTF16ToString(buf[:])), nil return common.ConvertDOSPath(windows.UTF16ToString(buf[:])), nil
} }
func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
func (p *Process) CmdlineWithContext(_ context.Context) (string, error) { func (p *Process) CmdlineWithContext(_ context.Context) (string, error) {
cmdline, err := getProcessCommandLine(p.Pid) cmdline, err := getProcessCommandLine(p.Pid)
if err != nil { if err != nil {
@ -306,13 +307,6 @@ func (p *Process) CmdlineWithContext(_ context.Context) (string, error) {
return cmdline, nil return cmdline, nil
} }
// CmdlineSlice returns the command line arguments of the process as a slice with each
// element being an argument. This merely returns the CommandLine informations passed
// to the process split on the 0x20 ASCII character.
func (p *Process) CmdlineSlice() ([]string, error) {
return p.CmdlineSliceWithContext(context.Background())
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
cmdline, err := p.CmdlineWithContext(ctx) cmdline, err := p.CmdlineWithContext(ctx)
if err != nil { if err != nil {
@ -330,16 +324,9 @@ func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
return ru.CreationTime.Nanoseconds() / 1000000, nil return ru.CreationTime.Nanoseconds() / 1000000, nil
} }
func (p *Process) Cwd() (string, error) {
return p.CwdWithContext(context.Background())
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) { func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Parent() (*Process, error) {
return p.ParentWithContext(context.Background())
}
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
ppid, err := p.PpidWithContext(ctx) ppid, err := p.PpidWithContext(ctx)
@ -347,28 +334,17 @@ func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
return nil, fmt.Errorf("could not get ParentProcessID: %s", err) return nil, fmt.Errorf("could not get ParentProcessID: %s", err)
} }
return NewProcess(ppid) return NewProcessWithContext(ctx, ppid)
}
func (p *Process) Status() (string, error) {
return p.StatusWithContext(context.Background())
} }
func (p *Process) StatusWithContext(ctx context.Context) (string, error) { func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError return "", common.ErrNotImplementedError
} }
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
return false, common.ErrNotImplementedError return false, common.ErrNotImplementedError
} }
func (p *Process) Username() (string, error) {
return p.UsernameWithContext(context.Background())
}
func (p *Process) UsernameWithContext(ctx context.Context) (string, error) { func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
pid := p.Pid pid := p.Pid
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid)) c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
@ -392,30 +368,16 @@ func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
return domain + "\\" + user, err return domain + "\\" + user, err
} }
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
var uids []int32 return nil, common.ErrNotImplementedError
return uids, common.ErrNotImplementedError
}
func (p *Process) Gids() ([]int32, error) {
return p.GidsWithContext(context.Background())
} }
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
var gids []int32 return nil, common.ErrNotImplementedError
return gids, common.ErrNotImplementedError
} }
func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) {
var groups []int32 return nil, common.ErrNotImplementedError
return groups, common.ErrNotImplementedError
}
func (p *Process) Terminal() (string, error) {
return p.TerminalWithContext(context.Background())
} }
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) { func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
@ -434,11 +396,6 @@ var priorityClasses = map[int]int32{
0x00000100: 24, // REALTIME_PRIORITY_CLASS 0x00000100: 24, // REALTIME_PRIORITY_CLASS
} }
// Nice returns priority in Windows
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) { func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(p.Pid)) c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(p.Pid))
if err != nil { if err != nil {
@ -455,34 +412,17 @@ func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
} }
return priority, nil return priority, nil
} }
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())
}
func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) { func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) Rlimit() ([]RlimitStat, error) {
return p.RlimitWithContext(context.Background())
}
func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) { func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
var rlimit []RlimitStat return nil, common.ErrNotImplementedError
return rlimit, common.ErrNotImplementedError
}
func (p *Process) RlimitUsage(gatherUsed bool) ([]RlimitStat, error) {
return p.RlimitUsageWithContext(context.Background(), gatherUsed)
} }
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) { func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
var rlimit []RlimitStat return nil, common.ErrNotImplementedError
return rlimit, common.ErrNotImplementedError
}
func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.IOCountersWithContext(context.Background())
} }
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) { func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
@ -505,41 +445,32 @@ func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, e
return stats, nil return stats, nil
} }
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return p.NumCtxSwitchesWithContext(context.Background())
}
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) { func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) NumFDs() (int32, error) {
return p.NumFDsWithContext(context.Background())
}
func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) { func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func (p *Process) NumThreads() (int32, error) {
return p.NumThreadsWithContext(context.Background())
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
_, ret, _, err := getFromSnapProcess(p.Pid) ppid, ret, _, err := getFromSnapProcess(p.Pid)
if err != nil { if err != nil {
return 0, err return 0, err
} }
// if no errors and not cached already, cache ppid
p.parent = ppid
if 0 == p.getPpid() {
p.setPpid(ppid)
}
return ret, nil return ret, nil
} }
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
return p.ThreadsWithContext(context.Background())
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) { func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
ret := make(map[int32]*cpu.TimesStat) return nil, common.ErrNotImplementedError
return ret, common.ErrNotImplementedError
}
func (p *Process) Times() (*cpu.TimesStat, error) {
return p.TimesWithContext(context.Background())
} }
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
@ -565,16 +496,10 @@ func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error)
System: kernel, System: kernel,
}, nil }, nil
} }
func (p *Process) CPUAffinity() ([]int32, error) {
return p.CPUAffinityWithContext(context.Background())
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) { func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
mem, err := getMemoryInfo(p.Pid) mem, err := getMemoryInfo(p.Pid)
@ -589,26 +514,15 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e
return ret, nil return ret, nil
} }
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) { func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) PageFaults() (*PageFaultsStat, error) {
return p.PageFaultsWithContext(context.Background())
}
func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) { func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
out := []*Process{} out := []*Process{}
snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, uint32(0)) snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, uint32(0))
@ -623,7 +537,7 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
} }
for { for {
if pe32.ParentProcessID == uint32(p.Pid) { if pe32.ParentProcessID == uint32(p.Pid) {
p, err := NewProcess(int32(pe32.ProcessID)) p, err := NewProcessWithContext(ctx, int32(pe32.ProcessID))
if err == nil { if err == nil {
out = append(out, p) out = append(out, p)
} }
@ -635,59 +549,30 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
return out, nil return out, nil
} }
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) { func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
}
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) { func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
return net.ConnectionsPidWithContext(ctx, "all", p.Pid) return net.ConnectionsPidWithContext(ctx, "all", p.Pid)
} }
func (p *Process) ConnectionsMax(max int) ([]net.ConnectionStat, error) {
return p.ConnectionsMaxWithContext(context.Background(), max)
}
func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) { func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) {
return []net.ConnectionStat{}, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
}
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
} }
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) { func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
return nil, common.ErrNotImplementedError return nil, common.ErrNotImplementedError
} }
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
}
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) { func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
var ret []MemoryMapsStat return nil, common.ErrNotImplementedError
return &ret, common.ErrNotImplementedError
} }
func (p *Process) SendSignal(sig windows.Signal) error { func (p *Process) SendSignalWithContext(ctx context.Context, sig syscall.Signal) error {
return p.SendSignalWithContext(context.Background(), sig)
}
func (p *Process) SendSignalWithContext(ctx context.Context, sig windows.Signal) error {
return common.ErrNotImplementedError return common.ErrNotImplementedError
} }
func (p *Process) Suspend() error {
return p.SuspendWithContext(context.Background())
}
func (p *Process) SuspendWithContext(ctx context.Context) error { func (p *Process) SuspendWithContext(ctx context.Context) error {
c, err := windows.OpenProcess(windows.PROCESS_SUSPEND_RESUME, false, uint32(p.Pid)) c, err := windows.OpenProcess(windows.PROCESS_SUSPEND_RESUME, false, uint32(p.Pid))
if err != nil { if err != nil {
@ -695,7 +580,7 @@ func (p *Process) SuspendWithContext(ctx context.Context) error {
} }
defer windows.CloseHandle(c) defer windows.CloseHandle(c)
r1, _, _ := procNtSuspendProcess.Call(uintptr(unsafe.Pointer(c))) r1, _, _ := procNtSuspendProcess.Call(uintptr(c))
if r1 != 0 { if r1 != 0 {
// See https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55 // See https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
return fmt.Errorf("NtStatus='0x%.8X'", r1) return fmt.Errorf("NtStatus='0x%.8X'", r1)
@ -704,10 +589,6 @@ func (p *Process) SuspendWithContext(ctx context.Context) error {
return nil return nil
} }
func (p *Process) Resume() error {
return p.ResumeWithContext(context.Background())
}
func (p *Process) ResumeWithContext(ctx context.Context) error { func (p *Process) ResumeWithContext(ctx context.Context) error {
c, err := windows.OpenProcess(windows.PROCESS_SUSPEND_RESUME, false, uint32(p.Pid)) c, err := windows.OpenProcess(windows.PROCESS_SUSPEND_RESUME, false, uint32(p.Pid))
if err != nil { if err != nil {
@ -715,7 +596,7 @@ func (p *Process) ResumeWithContext(ctx context.Context) error {
} }
defer windows.CloseHandle(c) defer windows.CloseHandle(c)
r1, _, _ := procNtResumeProcess.Call(uintptr(unsafe.Pointer(c))) r1, _, _ := procNtResumeProcess.Call(uintptr(c))
if r1 != 0 { if r1 != 0 {
// See https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55 // See https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
return fmt.Errorf("NtStatus='0x%.8X'", r1) return fmt.Errorf("NtStatus='0x%.8X'", r1)
@ -724,10 +605,6 @@ func (p *Process) ResumeWithContext(ctx context.Context) error {
return nil return nil
} }
func (p *Process) Terminate() error {
return p.TerminateWithContext(context.Background())
}
func (p *Process) TerminateWithContext(ctx context.Context) error { func (p *Process) TerminateWithContext(ctx context.Context) error {
proc, err := windows.OpenProcess(windows.PROCESS_TERMINATE, false, uint32(p.Pid)) proc, err := windows.OpenProcess(windows.PROCESS_TERMINATE, false, uint32(p.Pid))
if err != nil { if err != nil {
@ -738,15 +615,26 @@ func (p *Process) TerminateWithContext(ctx context.Context) error {
return err return err
} }
func (p *Process) Kill() error {
return p.KillWithContext(context.Background())
}
func (p *Process) KillWithContext(ctx context.Context) error { func (p *Process) KillWithContext(ctx context.Context) error {
process := os.Process{Pid: int(p.Pid)} process := os.Process{Pid: int(p.Pid)}
return process.Kill() return process.Kill()
} }
// retrieve Ppid in a thread-safe manner
func (p *Process) getPpid() int32 {
p.parentMutex.RLock()
defer p.parentMutex.RUnlock()
return p.parent
}
// cache Ppid in a thread-safe manner (WINDOWS ONLY)
// see https://psutil.readthedocs.io/en/latest/#psutil.Process.ppid
func (p *Process) setPpid(ppid int32) {
p.parentMutex.Lock()
defer p.parentMutex.Unlock()
p.parent = ppid
}
func getFromSnapProcess(pid int32) (int32, int32, string, error) { func getFromSnapProcess(pid int32) (int32, int32, string, error) {
snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, uint32(pid)) snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, uint32(pid))
if err != nil { if err != nil {
@ -770,11 +658,6 @@ func getFromSnapProcess(pid int32) (int32, int32, string, error) {
return 0, 0, "", fmt.Errorf("couldn't find pid: %d", pid) return 0, 0, "", fmt.Errorf("couldn't find pid: %d", pid)
} }
// Get processes
func Processes() ([]*Process, error) {
return ProcessesWithContext(context.Background())
}
func ProcessesWithContext(ctx context.Context) ([]*Process, error) { func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
out := []*Process{} out := []*Process{}
@ -784,7 +667,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
} }
for _, pid := range pids { for _, pid := range pids {
p, err := NewProcess(pid) p, err := NewProcessWithContext(ctx, pid)
if err != nil { if err != nil {
continue continue
} }
@ -1002,7 +885,7 @@ func convertUTF16ToString(src []byte) string {
srcIdx := 0 srcIdx := 0
for i := 0; i < srcLen; i++ { for i := 0; i < srcLen; i++ {
codePoints[i] = uint16(src[srcIdx]) | uint16(src[srcIdx+1]<<8) codePoints[i] = uint16(src[srcIdx]) | uint16(src[srcIdx+1])<<8
srcIdx += 2 srcIdx += 2
} }
return syscall.UTF16ToString(codePoints) return syscall.UTF16ToString(codePoints)

2
vendor/modules.txt vendored
View File

@ -332,7 +332,7 @@ github.com/rcrowley/go-metrics
github.com/robfig/go-cache github.com/robfig/go-cache
# github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b => github.com/satori/go.uuid v1.2.0 # github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b => github.com/satori/go.uuid v1.2.0
github.com/satori/go.uuid github.com/satori/go.uuid
# github.com/shirou/gopsutil v2.20.7+incompatible # github.com/shirou/gopsutil v3.20.11+incompatible
github.com/shirou/gopsutil/cpu github.com/shirou/gopsutil/cpu
github.com/shirou/gopsutil/internal/common github.com/shirou/gopsutil/internal/common
github.com/shirou/gopsutil/mem github.com/shirou/gopsutil/mem