parent
2e7a2a07ac
commit
9b0a8dbb07
2
go.mod
2
go.mod
|
@ -26,7 +26,7 @@ require (
|
|||
github.com/pquerna/cachecontrol v0.0.0-20200819021114-67c6ae64274f // 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/shirou/gopsutil v2.20.7+incompatible
|
||||
github.com/shirou/gopsutil v3.20.11+incompatible
|
||||
github.com/spaolacci/murmur3 v1.1.0
|
||||
github.com/spf13/viper v1.7.1
|
||||
github.com/streadway/amqp v1.0.0
|
||||
|
|
2
go.sum
2
go.sum
|
@ -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.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 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/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=
|
||||
|
|
|
@ -63,7 +63,8 @@ func gatherFields(m map[string]string) (map[string]string, error) {
|
|||
for k, v := range m {
|
||||
output, err := exec(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
logger.Errorf("get %s by exec %v err:%v", k, v, err)
|
||||
continue
|
||||
}
|
||||
ret[k] = output
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ type SysSection struct {
|
|||
PluginRemote bool `yaml:"pluginRemote"`
|
||||
Interval int `yaml:"interval"`
|
||||
Timeout int `yaml:"timeout"`
|
||||
FsRWEnable bool `yaml:"fsRWEnable"`
|
||||
}
|
||||
|
||||
type MountIgnoreSection struct {
|
||||
|
|
|
@ -29,7 +29,6 @@ func BuildMappers() {
|
|||
IOStatsMetrics,
|
||||
NfMetrics,
|
||||
FsKernelMetrics,
|
||||
FsRWMetrics,
|
||||
ProcsNumMetrics,
|
||||
EntityNumMetrics,
|
||||
NtpOffsetMetrics,
|
||||
|
@ -46,6 +45,17 @@ func BuildMappers() {
|
|||
Interval: interval,
|
||||
},
|
||||
}
|
||||
|
||||
if sys.Config.FsRWEnable {
|
||||
Mapper := FuncsAndInterval{
|
||||
Fs: []func() []*dataobj.MetricValue{
|
||||
FsRWMetrics,
|
||||
},
|
||||
Interval: interval,
|
||||
}
|
||||
Mappers = append(Mappers, Mapper)
|
||||
}
|
||||
|
||||
} else {
|
||||
log.Println("sys collect enable is false.")
|
||||
Mappers = []FuncsAndInterval{
|
||||
|
|
|
@ -149,7 +149,9 @@ func PercentWithContext(ctx context.Context, interval time.Duration, percpu bool
|
|||
return nil, err
|
||||
}
|
||||
|
||||
time.Sleep(interval)
|
||||
if err := common.Sleep(ctx, interval); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// And at the end of the interval.
|
||||
cpuTimes2, err := Times(percpu)
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -311,7 +312,29 @@ func CountsWithContext(ctx context.Context, logical bool) (int, error) {
|
|||
}
|
||||
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")
|
||||
lines, err := common.ReadLines(filename)
|
||||
if err != nil {
|
||||
|
|
|
@ -32,7 +32,6 @@ const (
|
|||
CTLKern = 1 // "high kernel": proc, limits
|
||||
CTLHw = 6 // CTL_HW
|
||||
SMT = 24 // HW_SMT
|
||||
NCpuOnline = 25 // HW_NCPUONLINE
|
||||
KernCptime = 40 // KERN_CPTIME
|
||||
KernCptime2 = 71 // KERN_CPTIME2
|
||||
)
|
||||
|
@ -163,25 +162,17 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
|
|||
|
||||
c := InfoStat{}
|
||||
|
||||
var u32 uint32
|
||||
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)
|
||||
mhz, err := unix.SysctlUint32("hw.cpuspeed")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.Mhz = float64(mhz)
|
||||
|
||||
var ncpu int32
|
||||
br := bytes.NewReader(buf)
|
||||
err = binary.Read(br, binary.LittleEndian, &ncpu)
|
||||
ncpu, err := unix.SysctlUint32("hw.ncpuonline")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.Cores = ncpu
|
||||
c.Cores = int32(ncpu)
|
||||
|
||||
if c.ModelName, err = unix.Sysctl("hw.model"); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -326,7 +326,6 @@ func GetEnv(key string, dfault string, combineWith ...string) string {
|
|||
copy(all[1:], combineWith)
|
||||
return filepath.Join(all...)
|
||||
}
|
||||
panic("invalid switch case")
|
||||
}
|
||||
|
||||
func HostProc(combineWith ...string) string {
|
||||
|
|
|
@ -36,7 +36,7 @@ func CallSyscall(mib []int32) ([]byte, uint64, error) {
|
|||
// get required buffer size
|
||||
length := uint64(0)
|
||||
_, _, 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(miblen),
|
||||
0,
|
||||
|
@ -54,7 +54,7 @@ func CallSyscall(mib []int32) ([]byte, uint64, error) {
|
|||
// get proc info itself
|
||||
buf := make([]byte, length)
|
||||
_, _, 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(miblen),
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -110,9 +111,24 @@ func Virtualization() (string, string, error) {
|
|||
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) {
|
||||
var system string
|
||||
var role string
|
||||
var system, 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")
|
||||
if PathExists(filename) {
|
||||
|
@ -231,6 +247,17 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) {
|
|||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ package common
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
@ -69,13 +70,13 @@ var (
|
|||
ProcNtWow64QueryInformationProcess64 = ModNt.NewProc("NtWow64QueryInformationProcess64")
|
||||
ProcNtWow64ReadVirtualMemory64 = ModNt.NewProc("NtWow64ReadVirtualMemory64")
|
||||
|
||||
PdhOpenQuery = ModPdh.NewProc("PdhOpenQuery")
|
||||
PdhAddCounter = ModPdh.NewProc("PdhAddCounterW")
|
||||
PdhCollectQueryData = ModPdh.NewProc("PdhCollectQueryData")
|
||||
PdhGetFormattedCounterValue = ModPdh.NewProc("PdhGetFormattedCounterValue")
|
||||
PdhCloseQuery = ModPdh.NewProc("PdhCloseQuery")
|
||||
PdhOpenQuery = ModPdh.NewProc("PdhOpenQuery")
|
||||
PdhAddCounter = ModPdh.NewProc("PdhAddCounterW")
|
||||
PdhCollectQueryData = ModPdh.NewProc("PdhCollectQueryData")
|
||||
PdhGetFormattedCounterValue = ModPdh.NewProc("PdhGetFormattedCounterValue")
|
||||
PdhCloseQuery = ModPdh.NewProc("PdhCloseQuery")
|
||||
|
||||
procQueryDosDeviceW = Modkernel32.NewProc("QueryDosDeviceW")
|
||||
procQueryDosDeviceW = Modkernel32.NewProc("QueryDosDeviceW")
|
||||
)
|
||||
|
||||
type FILETIME struct {
|
||||
|
@ -93,7 +94,7 @@ func BytePtrToString(p *uint8) string {
|
|||
return string(a[:i])
|
||||
}
|
||||
|
||||
// CounterInfo
|
||||
// CounterInfo struct is used to track a windows performance counter
|
||||
// copied from https://github.com/mackerelio/mackerel-agent/
|
||||
type CounterInfo struct {
|
||||
PostName string
|
||||
|
@ -101,7 +102,7 @@ type CounterInfo struct {
|
|||
Counter windows.Handle
|
||||
}
|
||||
|
||||
// CreateQuery XXX
|
||||
// CreateQuery with a PdhOpenQuery call
|
||||
// copied from https://github.com/mackerelio/mackerel-agent/
|
||||
func CreateQuery() (windows.Handle, error) {
|
||||
var query windows.Handle
|
||||
|
@ -112,7 +113,7 @@ func CreateQuery() (windows.Handle, error) {
|
|||
return query, nil
|
||||
}
|
||||
|
||||
// CreateCounter XXX
|
||||
// CreateCounter with a PdhAddCounter call
|
||||
func CreateCounter(query windows.Handle, pname, cname string) (*CounterInfo, error) {
|
||||
var counter windows.Handle
|
||||
r, _, err := PdhAddCounter.Call(
|
||||
|
@ -130,6 +131,62 @@ func CreateCounter(query windows.Handle, pname, cname string) (*CounterInfo, err
|
|||
}, 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
|
||||
func WMIQueryWithContext(ctx context.Context, query string, dst interface{}, connectServerArgs ...interface{}) error {
|
||||
if _, ok := ctx.Deadline(); !ok {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -73,86 +73,226 @@ func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *Virtu
|
|||
value := strings.TrimSpace(fields[1])
|
||||
value = strings.Replace(value, " kB", "", -1)
|
||||
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx,err
|
||||
}
|
||||
switch key {
|
||||
case "MemTotal":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.Total = t * 1024
|
||||
case "MemFree":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.Free = t * 1024
|
||||
case "MemAvailable":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
memavail = true
|
||||
ret.Available = t * 1024
|
||||
case "Buffers":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.Buffers = t * 1024
|
||||
case "Cached":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.Cached = t * 1024
|
||||
case "Active":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.Active = t * 1024
|
||||
case "Inactive":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.Inactive = t * 1024
|
||||
case "Active(anon)":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
retEx.ActiveAnon = t * 1024
|
||||
case "Inactive(anon)":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
retEx.InactiveAnon = t * 1024
|
||||
case "Active(file)":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
activeFile = true
|
||||
retEx.ActiveFile = t * 1024
|
||||
case "Inactive(file)":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
inactiveFile = true
|
||||
retEx.InactiveFile = t * 1024
|
||||
case "Unevictable":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
retEx.Unevictable = t * 1024
|
||||
case "Writeback":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.Writeback = t * 1024
|
||||
case "WritebackTmp":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.WritebackTmp = t * 1024
|
||||
case "Dirty":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.Dirty = t * 1024
|
||||
case "Shmem":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.Shared = t * 1024
|
||||
case "Slab":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.Slab = t * 1024
|
||||
case "SReclaimable":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
sReclaimable = true
|
||||
ret.SReclaimable = t * 1024
|
||||
case "SUnreclaim":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.SUnreclaim = t * 1024
|
||||
case "PageTables":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.PageTables = t * 1024
|
||||
case "SwapCached":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.SwapCached = t * 1024
|
||||
case "CommitLimit":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.CommitLimit = t * 1024
|
||||
case "Committed_AS":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.CommittedAS = t * 1024
|
||||
case "HighTotal":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.HighTotal = t * 1024
|
||||
case "HighFree":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.HighFree = t * 1024
|
||||
case "LowTotal":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.LowTotal = t * 1024
|
||||
case "LowFree":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.LowFree = t * 1024
|
||||
case "SwapTotal":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.SwapTotal = t * 1024
|
||||
case "SwapFree":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.SwapFree = t * 1024
|
||||
case "Mapped":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.Mapped = t * 1024
|
||||
case "VmallocTotal":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.VMallocTotal = t * 1024
|
||||
case "VmallocUsed":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.VMallocUsed = t * 1024
|
||||
case "VmallocChunk":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.VMallocChunk = t * 1024
|
||||
case "HugePages_Total":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.HugePagesTotal = t
|
||||
case "HugePages_Free":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.HugePagesFree = t
|
||||
case "Hugepagesize":
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, retEx, err
|
||||
}
|
||||
ret.HugePageSize = t * 1024
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"os/exec"
|
||||
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func GetPageSize() (uint64, error) {
|
||||
|
@ -18,17 +19,7 @@ func GetPageSize() (uint64, error) {
|
|||
}
|
||||
|
||||
func GetPageSizeWithContext(ctx context.Context) (uint64, error) {
|
||||
mib := []int32{CTLVm, VmUvmexp}
|
||||
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)
|
||||
uvmexp, err := unix.SysctlUvmexp("vm.uvmexp")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -40,17 +31,7 @@ func VirtualMemory() (*VirtualMemoryStat, error) {
|
|||
}
|
||||
|
||||
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
|
||||
mib := []int32{CTLVm, VmUvmexp}
|
||||
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)
|
||||
uvmexp, err := unix.SysctlUvmexp("vm.uvmexp")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -69,8 +50,8 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
|
|||
ret.Used = ret.Total - ret.Available
|
||||
ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0
|
||||
|
||||
mib = []int32{CTLVfs, VfsGeneric, VfsBcacheStat}
|
||||
buf, length, err = common.CallSyscall(mib)
|
||||
mib := []int32{CTLVfs, VfsGeneric, VfsBcacheStat}
|
||||
buf, length, err := common.CallSyscall(mib)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -78,7 +59,7 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
|
|||
return nil, fmt.Errorf("short syscall ret %d bytes", length)
|
||||
}
|
||||
var bcs Bcachestats
|
||||
br = bytes.NewReader(buf)
|
||||
br := bytes.NewReader(buf)
|
||||
err = common.Read(br, binary.LittleEndian, &bcs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -4,105 +4,15 @@
|
|||
package mem
|
||||
|
||||
const (
|
||||
CTLVm = 2
|
||||
CTLVfs = 10
|
||||
VmUvmexp = 4
|
||||
VfsGeneric = 0
|
||||
VfsBcacheStat = 3
|
||||
)
|
||||
|
||||
const (
|
||||
sizeOfUvmexp = 0x154
|
||||
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 {
|
||||
Numbufs int64
|
||||
Numbufpages int64
|
||||
|
|
|
@ -269,7 +269,7 @@ func FilterCounters() ([]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) {
|
||||
|
@ -289,5 +289,5 @@ func ProtoCounters(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
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ package net
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -109,7 +108,7 @@ func FilterCounters() ([]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) {
|
||||
|
@ -117,7 +116,7 @@ func ConntrackStats(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
|
||||
|
@ -129,5 +128,5 @@ func ProtoCounters(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
|
||||
}
|
||||
|
|
|
@ -696,7 +696,7 @@ func decodeAddress(family uint32, src string) (Addr, error) {
|
|||
return Addr{}, fmt.Errorf("does not contain port, %s", src)
|
||||
}
|
||||
addr := t[0]
|
||||
port, err := strconv.ParseInt("0x"+t[1], 0, 64)
|
||||
port, err := strconv.ParseUint(t[1], 16, 16)
|
||||
if err != nil {
|
||||
return Addr{}, fmt.Errorf("invalid port, %s", src)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ package net
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
|
@ -153,7 +152,7 @@ func FilterCounters() ([]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) {
|
||||
|
@ -173,7 +172,7 @@ func ProtoCounters(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) {
|
||||
|
|
|
@ -4,7 +4,6 @@ package net
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
|
@ -323,7 +322,7 @@ func FilterCounters() ([]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) {
|
||||
|
@ -344,7 +343,7 @@ func ProtoCounters(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 {
|
||||
|
@ -548,7 +547,7 @@ func getUDPConnections(family uint32) ([]ConnectionStat, error) {
|
|||
mibs := (*mibUDPRowOwnerPid)(unsafe.Pointer(&buf[index]))
|
||||
ns := mibs.convertToConnectionStat()
|
||||
stats = append(stats, ns)
|
||||
case kindUDP4.family:
|
||||
case kindUDP6.family:
|
||||
mibs := (*mibUDP6RowOwnerPid)(unsafe.Pointer(&buf[index]))
|
||||
ns := mibs.convertToConnectionStat()
|
||||
stats = append(stats, ns)
|
||||
|
|
|
@ -6,11 +6,14 @@ import (
|
|||
"errors"
|
||||
"runtime"
|
||||
"sort"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
"github.com/shirou/gopsutil/mem"
|
||||
"github.com/shirou/gopsutil/net"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -24,6 +27,7 @@ type Process struct {
|
|||
name string
|
||||
status string
|
||||
parent int32
|
||||
parentMutex *sync.RWMutex // for windows ppid cache
|
||||
numCtxSwitches *NumCtxSwitchesStat
|
||||
uids []int32
|
||||
gids []int32
|
||||
|
@ -150,21 +154,34 @@ func PidsWithContext(ctx context.Context) ([]int32, error) {
|
|||
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
|
||||
// checks that the process exists. Other method on Process can be used
|
||||
// to get more information about the process. An error will be returned
|
||||
// if the process does not exist.
|
||||
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 {
|
||||
return p, err
|
||||
}
|
||||
if !exists {
|
||||
return p, ErrorProcessNotRunning
|
||||
}
|
||||
p.CreateTime()
|
||||
p.CreateTimeWithContext(ctx)
|
||||
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) {
|
||||
cpuTimes, err := p.Times()
|
||||
cpuTimes, err := p.TimesWithContext(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -201,8 +218,10 @@ func (p *Process) PercentWithContext(ctx context.Context, interval time.Duration
|
|||
if interval > 0 {
|
||||
p.lastCPUTimes = cpuTimes
|
||||
p.lastCPUTime = now
|
||||
time.Sleep(interval)
|
||||
cpuTimes, err = p.Times()
|
||||
if err := common.Sleep(ctx, interval); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
cpuTimes, err = p.TimesWithContext(ctx)
|
||||
now = time.Now()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@ -234,7 +253,7 @@ func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
|
|||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
p2, err := NewProcess(p.Pid)
|
||||
p2, err := NewProcessWithContext(ctx, p.Pid)
|
||||
if err == ErrorProcessNotRunning {
|
||||
return false, nil
|
||||
}
|
||||
|
@ -274,13 +293,13 @@ func (p *Process) MemoryPercent() (float32, error) {
|
|||
}
|
||||
|
||||
func (p *Process) MemoryPercentWithContext(ctx context.Context) (float32, error) {
|
||||
machineMemory, err := mem.VirtualMemory()
|
||||
machineMemory, err := mem.VirtualMemoryWithContext(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
total := machineMemory.Total
|
||||
|
||||
processMemory, err := p.MemoryInfo()
|
||||
processMemory, err := p.MemoryInfoWithContext(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -295,12 +314,12 @@ func (p *Process) CPUPercent() (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 {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
cput, err := p.Times()
|
||||
cput, err := p.TimesWithContext(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -316,5 +335,210 @@ func (p *Process) CPUPercentWithContext(ctx context.Context) (float64, error) {
|
|||
|
||||
// Groups returns all group IDs(include supplementary groups) of the process as a slice of the int
|
||||
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())
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -3,16 +3,13 @@
|
|||
package process
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
"github.com/shirou/gopsutil/internal/common"
|
||||
|
@ -38,13 +35,6 @@ type _Ctype_struct___0 struct {
|
|||
Pad uint64
|
||||
}
|
||||
|
||||
// MemoryInfoExStat is different between OSes
|
||||
type MemoryInfoExStat struct {
|
||||
}
|
||||
|
||||
type MemoryMapsStat struct {
|
||||
}
|
||||
|
||||
func pidsWithContext(ctx context.Context) ([]int32, error) {
|
||||
var ret []int32
|
||||
|
||||
|
@ -64,10 +54,6 @@ func pidsWithContext(ctx context.Context) ([]int32, error) {
|
|||
return ret, nil
|
||||
}
|
||||
|
||||
func (p *Process) Ppid() (int32, error) {
|
||||
return p.PpidWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
|
||||
r, err := callPsWithContext(ctx, "ppid", p.Pid, false)
|
||||
if err != nil {
|
||||
|
@ -81,9 +67,6 @@ func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
|
|||
|
||||
return int32(v), err
|
||||
}
|
||||
func (p *Process) Name() (string, error) {
|
||||
return p.NameWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -109,18 +92,6 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
|||
|
||||
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) {
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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
|
||||
// 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) {
|
||||
r, err := callPsWithContext(ctx, "command", p.Pid, false)
|
||||
if err != nil {
|
||||
|
@ -177,38 +144,23 @@ func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
|
|||
start := time.Now().Add(-elapsed)
|
||||
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) {
|
||||
rr, err := common.CallLsofWithContext(ctx, invoke, p.Pid, "-FR")
|
||||
out, err := common.CallLsofWithContext(ctx, invoke, p.Pid, "-FR")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, r := range rr {
|
||||
if strings.HasPrefix(r, "p") { // skip if process
|
||||
continue
|
||||
for _, line := range out {
|
||||
if len(line) >= 1 && line[0] == 'R' {
|
||||
v, err := strconv.Atoi(line[1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewProcessWithContext(ctx, int32(v))
|
||||
}
|
||||
l := string(r)
|
||||
v, err := strconv.Atoi(strings.Replace(l, "R", "", 1))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewProcess(int32(v))
|
||||
}
|
||||
return nil, fmt.Errorf("could not find parent line")
|
||||
}
|
||||
func (p *Process) Status() (string, error) {
|
||||
return p.StatusWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
|
||||
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
|
||||
}
|
||||
|
||||
func (p *Process) Foreground() (bool, error) {
|
||||
return p.ForegroundWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
|
||||
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
|
||||
pid := p.Pid
|
||||
|
@ -237,10 +185,6 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
|
|||
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) {
|
||||
k, err := p.getKProc()
|
||||
if err != nil {
|
||||
|
@ -252,9 +196,6 @@ func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
|
|||
|
||||
return []int32{userEffectiveUID}, nil
|
||||
}
|
||||
func (p *Process) Gids() ([]int32, error) {
|
||||
return p.GidsWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
|
||||
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) {
|
||||
k, err := p.getKProc()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, common.ErrNotImplementedError
|
||||
// k, err := p.getKProc()
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
groups := make([]int32, k.Eproc.Ucred.Ngroups)
|
||||
for i := int16(0); i < k.Eproc.Ucred.Ngroups; i++ {
|
||||
groups[i] = int32(k.Eproc.Ucred.Groups[i])
|
||||
}
|
||||
// groups := make([]int32, k.Eproc.Ucred.Ngroups)
|
||||
// for i := int16(0); i < k.Eproc.Ucred.Ngroups; i++ {
|
||||
// groups[i] = int32(k.Eproc.Ucred.Groups[i])
|
||||
// }
|
||||
|
||||
return groups, nil
|
||||
}
|
||||
func (p *Process) Terminal() (string, error) {
|
||||
return p.TerminalWithContext(context.Background())
|
||||
// return groups, nil
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
}
|
||||
func (p *Process) Nice() (int32, error) {
|
||||
return p.NiceWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -313,53 +249,10 @@ func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
|
|||
}
|
||||
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) {
|
||||
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) {
|
||||
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
|
||||
}
|
||||
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) {
|
||||
var t int
|
||||
|
@ -422,9 +307,6 @@ func convertCPUTimes(s string) (ret float64, err error) {
|
|||
t += h
|
||||
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) {
|
||||
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
|
||||
}
|
||||
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) {
|
||||
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
|
||||
}
|
||||
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) {
|
||||
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))
|
||||
for _, pid := range pids {
|
||||
np, err := NewProcess(pid)
|
||||
np, err := NewProcessWithContext(ctx, pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -522,50 +375,12 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
|
|||
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) {
|
||||
return net.ConnectionsPid("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)
|
||||
return net.ConnectionsPidWithContext(ctx, "all", p.Pid)
|
||||
}
|
||||
|
||||
func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) {
|
||||
return net.ConnectionsPidMax("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())
|
||||
return net.ConnectionsPidMaxWithContext(ctx, "all", p.Pid, max)
|
||||
}
|
||||
|
||||
func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
||||
|
@ -577,7 +392,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
|||
}
|
||||
|
||||
for _, pid := range pids {
|
||||
p, err := NewProcess(pid)
|
||||
p, err := NewProcessWithContext(ctx, pid)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@ -587,39 +402,12 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
|||
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:
|
||||
// http://unix.superglobalmegacorp.com/Net2/newsrc/sys/kinfo_proc.h.html
|
||||
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}
|
||||
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
|
||||
buf, err := unix.SysctlRaw("kern.proc.pid", int(p.Pid))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k, err := parseKinfoProc(buf)
|
||||
if err != nil {
|
||||
|
|
205
vendor/github.com/shirou/gopsutil/process/process_darwin_arm64.go
generated
vendored
Normal file
205
vendor/github.com/shirou/gopsutil/process/process_darwin_arm64.go
generated
vendored
Normal 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
|
||||
}
|
|
@ -29,10 +29,6 @@ type MemoryInfoExStat struct {
|
|||
}
|
||||
|
||||
func pidsWithContext(ctx context.Context) ([]int32, error) {
|
||||
return []int32{}, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func Processes() ([]*Process, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
|
@ -41,295 +37,168 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
|||
}
|
||||
|
||||
func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
|
||||
pids, err := PidsWithContext(ctx)
|
||||
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())
|
||||
return false, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
|
||||
return 0, common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Name() (string, error) {
|
||||
return p.NameWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
||||
return "", common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Tgid() (int32, error) {
|
||||
|
||||
func (p *Process) TgidWithContext(ctx context.Context) (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) {
|
||||
return "", common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Cmdline() (string, error) {
|
||||
return p.CmdlineWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
|
||||
return "", common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) CmdlineSlice() ([]string, error) {
|
||||
return p.CmdlineSliceWithContext(context.Background())
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Status() (string, error) {
|
||||
return p.StatusWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
|
||||
return "", common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Foreground() (bool, error) {
|
||||
return p.ForegroundWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
|
||||
return false, common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Uids() ([]int32, error) {
|
||||
return p.UidsWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
|
||||
return []int32{}, common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Gids() ([]int32, error) {
|
||||
return p.GidsWithContext(context.Background())
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
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) {
|
||||
return []int32{}, common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Terminal() (string, error) {
|
||||
return p.TerminalWithContext(context.Background())
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
|
||||
return "", common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Nice() (int32, error) {
|
||||
return p.NiceWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
|
||||
return 0, common.ErrNotImplementedError
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) IOCounters() (*IOCountersStat, error) {
|
||||
return p.IOCountersWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
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) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
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) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
|
||||
return p.OpenFilesWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
|
||||
return []OpenFilesStat{}, common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Connections() ([]net.ConnectionStat, error) {
|
||||
return p.ConnectionsWithContext(context.Background())
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
|
||||
return []net.ConnectionStat{}, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) ConnectionsMax(max int) ([]net.ConnectionStat, error) {
|
||||
return p.ConnectionsMaxWithContext(context.Background(), max)
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
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)
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
|
||||
return []net.IOCountersStat{}, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
|
||||
return p.MemoryMapsWithContext(context.Background(), grouped)
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
|
||||
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 {
|
||||
return common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Suspend() error {
|
||||
return p.SuspendWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) SuspendWithContext(ctx context.Context) error {
|
||||
return common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Resume() error {
|
||||
return p.ResumeWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) ResumeWithContext(ctx context.Context) error {
|
||||
return common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Terminate() error {
|
||||
return p.TerminateWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) TerminateWithContext(ctx context.Context) error {
|
||||
return common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Kill() error {
|
||||
return p.KillWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) KillWithContext(ctx context.Context) error {
|
||||
return common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Username() (string, error) {
|
||||
return p.UsernameWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
|
||||
return "", common.ErrNotImplementedError
|
||||
|
|
|
@ -5,7 +5,6 @@ package process
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
@ -17,16 +16,9 @@ import (
|
|||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// MemoryInfoExStat is different between OSes
|
||||
type MemoryInfoExStat struct {
|
||||
}
|
||||
|
||||
type MemoryMapsStat struct {
|
||||
}
|
||||
|
||||
func pidsWithContext(ctx context.Context) ([]int32, error) {
|
||||
var ret []int32
|
||||
procs, err := Processes()
|
||||
procs, err := ProcessesWithContext(ctx)
|
||||
if err != nil {
|
||||
return ret, nil
|
||||
}
|
||||
|
@ -38,10 +30,6 @@ func pidsWithContext(ctx context.Context) ([]int32, error) {
|
|||
return ret, nil
|
||||
}
|
||||
|
||||
func (p *Process) Ppid() (int32, error) {
|
||||
return p.PpidWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
|
||||
k, err := p.getKProc()
|
||||
if err != nil {
|
||||
|
@ -50,9 +38,6 @@ func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
|
|||
|
||||
return k.Ppid, nil
|
||||
}
|
||||
func (p *Process) Name() (string, error) {
|
||||
return p.NameWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -78,21 +63,11 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
|||
|
||||
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) {
|
||||
return "", common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) Cmdline() (string, error) {
|
||||
return p.CmdlineWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
|
||||
mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid}
|
||||
buf, _, err := common.CallSyscall(mib)
|
||||
|
@ -109,10 +84,6 @@ func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
|
|||
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) {
|
||||
mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid}
|
||||
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) {
|
||||
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) {
|
||||
return p, common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Status() (string, error) {
|
||||
return p.StatusWithContext(context.Background())
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (p *Process) Foreground() (bool, error) {
|
||||
return p.ForegroundWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
|
||||
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
|
||||
pid := p.Pid
|
||||
|
@ -199,10 +153,6 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
|
|||
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) {
|
||||
k, err := p.getKProc()
|
||||
if err != nil {
|
||||
|
@ -215,9 +165,6 @@ func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
|
|||
|
||||
return uids, nil
|
||||
}
|
||||
func (p *Process) Gids() ([]int32, error) {
|
||||
return p.GidsWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -244,9 +191,6 @@ func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) {
|
|||
|
||||
return groups, nil
|
||||
}
|
||||
func (p *Process) Terminal() (string, error) {
|
||||
return p.TerminalWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -263,9 +207,6 @@ func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
|
|||
|
||||
return termmap[ttyNr], nil
|
||||
}
|
||||
func (p *Process) Nice() (int32, error) {
|
||||
return p.NiceWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -274,32 +215,6 @@ func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
|
|||
}
|
||||
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) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -311,23 +226,6 @@ func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, e
|
|||
WriteCount: uint64(k.Rusage.Oublock),
|
||||
}, 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) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -337,17 +235,6 @@ func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
|
|||
|
||||
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) {
|
||||
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,
|
||||
}, 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) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -387,25 +264,6 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e
|
|||
VMS: uint64(k.Size),
|
||||
}, 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) {
|
||||
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))
|
||||
for _, pid := range pids {
|
||||
np, err := NewProcess(pid)
|
||||
np, err := NewProcessWithContext(ctx, pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -423,52 +281,14 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
|
|||
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) {
|
||||
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) {
|
||||
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
|
||||
}
|
||||
|
||||
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) {
|
||||
results := []*Process{}
|
||||
|
||||
|
@ -488,7 +308,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
|||
if err != nil {
|
||||
continue
|
||||
}
|
||||
p, err := NewProcess(int32(k.Pid))
|
||||
p, err := NewProcessWithContext(ctx, int32(k.Pid))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@ -499,18 +319,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
|||
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) {
|
||||
return p.getKProcWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) getKProcWithContext(ctx context.Context) (*KinfoProc, error) {
|
||||
mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid}
|
||||
|
||||
buf, length, err := common.CallSyscall(mib)
|
||||
|
|
|
@ -64,11 +64,6 @@ func (m MemoryMapsStat) String() string {
|
|||
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) {
|
||||
_, ppid, _, _, _, _, _, err := p.fillFromStatWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -77,11 +72,6 @@ func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
|
|||
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) {
|
||||
if p.name == "" {
|
||||
if err := p.fillFromStatusWithContext(ctx); err != nil {
|
||||
|
@ -91,41 +81,23 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
|||
return p.name, nil
|
||||
}
|
||||
|
||||
// Tgid returns tgid, a Linux-synonym for user-space Pid
|
||||
func (p *Process) Tgid() (int32, error) {
|
||||
func (p *Process) TgidWithContext(ctx context.Context) (int32, error) {
|
||||
if p.tgid == 0 {
|
||||
if err := p.fillFromStatusWithContext(context.Background()); err != nil {
|
||||
if err := p.fillFromStatusWithContext(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
return p.fillSliceFromCmdlineWithContext(ctx)
|
||||
}
|
||||
|
@ -138,20 +110,10 @@ func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
|
|||
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) {
|
||||
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) {
|
||||
err := p.fillFromStatusWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -160,16 +122,7 @@ func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
|
|||
if p.parent == 0 {
|
||||
return nil, fmt.Errorf("wrong number of parents")
|
||||
}
|
||||
return NewProcess(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())
|
||||
return NewProcessWithContext(ctx, p.parent)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
|
||||
pid := p.Pid
|
||||
|
@ -202,11 +150,6 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
|
|||
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) {
|
||||
err := p.fillFromStatusWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -215,11 +158,6 @@ func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
|
|||
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) {
|
||||
err := p.fillFromStatusWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -236,11 +174,6 @@ func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) {
|
|||
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) {
|
||||
t, _, _, _, _, _, _, err := p.fillFromStatWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -254,12 +187,6 @@ func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
|
|||
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) {
|
||||
_, _, _, _, _, nice, _, err := p.fillFromStatWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -268,29 +195,12 @@ func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
|
|||
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) {
|
||||
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) {
|
||||
return p.RlimitUsage(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)
|
||||
return p.RlimitUsageWithContext(ctx, false)
|
||||
}
|
||||
|
||||
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]
|
||||
switch rs.Resource {
|
||||
case RLIMIT_CPU:
|
||||
times, err := p.Times()
|
||||
times, err := p.TimesWithContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -323,7 +233,7 @@ func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) (
|
|||
case RLIMIT_RSS:
|
||||
rs.Used = uint64(p.memInfo.RSS)
|
||||
case RLIMIT_NOFILE:
|
||||
n, err := p.NumFDs()
|
||||
n, err := p.NumFDsWithContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -348,20 +258,10 @@ func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) (
|
|||
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) {
|
||||
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) {
|
||||
err := p.fillFromStatusWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -370,21 +270,11 @@ func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitche
|
|||
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) {
|
||||
_, fnames, err := p.fillFromfdListWithContext(ctx)
|
||||
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) {
|
||||
err := p.fillFromStatusWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -393,10 +283,6 @@ func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
|
|||
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) {
|
||||
ret := make(map[int32]*cpu.TimesStat)
|
||||
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
|
||||
}
|
||||
|
||||
// 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) {
|
||||
_, _, cpuTimes, _, _, _, _, err := p.fillFromStatWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -430,22 +311,10 @@ func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error)
|
|||
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) {
|
||||
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) {
|
||||
meminfo, _, err := p.fillFromStatmWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -454,11 +323,6 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e
|
|||
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) {
|
||||
_, memInfoEx, err := p.fillFromStatmWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -467,11 +331,6 @@ func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExSta
|
|||
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) {
|
||||
_, _, _, _, _, _, pageFaults, err := p.fillFromStatWithContext(ctx)
|
||||
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) {
|
||||
pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid)
|
||||
if err != nil {
|
||||
|
@ -496,7 +350,7 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
|
|||
}
|
||||
ret := make([]*Process, 0, len(pids))
|
||||
for _, pid := range pids {
|
||||
np, err := NewProcess(pid)
|
||||
np, err := NewProcessWithContext(ctx, pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -505,12 +359,6 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
|
|||
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) {
|
||||
_, ofs, err := p.fillFromfdWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -524,38 +372,17 @@ func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, er
|
|||
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) {
|
||||
return net.ConnectionsPid("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)
|
||||
return net.ConnectionsPidWithContext(ctx, "all", p.Pid)
|
||||
}
|
||||
|
||||
func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) {
|
||||
return net.ConnectionsPidMax("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)
|
||||
return net.ConnectionsPidMaxWithContext(ctx, "all", p.Pid, max)
|
||||
}
|
||||
|
||||
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
|
||||
filename := common.HostProc(strconv.Itoa(int(p.Pid)), "net/dev")
|
||||
return net.IOCountersByFile(pernic, filename)
|
||||
}
|
||||
|
||||
// MemoryMaps get memory maps from /proc/(pid)/smaps
|
||||
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
|
||||
return p.MemoryMapsWithContext(context.Background(), grouped)
|
||||
return net.IOCountersByFileWithContext(ctx, pernic, filename)
|
||||
}
|
||||
|
||||
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
|
||||
|
@ -1181,7 +1008,7 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui
|
|||
// docs). Note: I am assuming at least Linux 2.6.18
|
||||
iotime, err := strconv.ParseFloat(fields[i+40], 64)
|
||||
if err != nil {
|
||||
iotime = 0 // Ancient linux version, most likely
|
||||
iotime = 0 // Ancient linux version, most likely
|
||||
}
|
||||
|
||||
cpuTimes := &cpu.TimesStat{
|
||||
|
@ -1249,12 +1076,6 @@ func pidsWithContext(ctx context.Context) ([]int32, error) {
|
|||
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) {
|
||||
out := []*Process{}
|
||||
|
||||
|
@ -1264,7 +1085,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
|||
}
|
||||
|
||||
for _, pid := range pids {
|
||||
p, err := NewProcess(pid)
|
||||
p, err := NewProcessWithContext(ctx, pid)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -4,9 +4,7 @@ package process
|
|||
|
||||
import (
|
||||
"C"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
@ -20,16 +18,9 @@ import (
|
|||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// MemoryInfoExStat is different between OSes
|
||||
type MemoryInfoExStat struct {
|
||||
}
|
||||
|
||||
type MemoryMapsStat struct {
|
||||
}
|
||||
|
||||
func pidsWithContext(ctx context.Context) ([]int32, error) {
|
||||
var ret []int32
|
||||
procs, err := Processes()
|
||||
procs, err := ProcessesWithContext(ctx)
|
||||
if err != nil {
|
||||
return ret, nil
|
||||
}
|
||||
|
@ -41,10 +32,6 @@ func pidsWithContext(ctx context.Context) ([]int32, error) {
|
|||
return ret, nil
|
||||
}
|
||||
|
||||
func (p *Process) Ppid() (int32, error) {
|
||||
return p.PpidWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
|
||||
k, err := p.getKProc()
|
||||
if err != nil {
|
||||
|
@ -53,9 +40,6 @@ func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
|
|||
|
||||
return k.Ppid, nil
|
||||
}
|
||||
func (p *Process) Name() (string, error) {
|
||||
return p.NameWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -81,21 +65,11 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
|||
|
||||
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) {
|
||||
return "", common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) CmdlineSlice() ([]string, error) {
|
||||
return p.CmdlineSliceWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
|
||||
mib := []int32{CTLKern, KernProcArgs, p.Pid, KernProcArgv}
|
||||
buf, _, err := common.CallSyscall(mib)
|
||||
|
@ -119,12 +93,8 @@ func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error)
|
|||
return strParts, nil
|
||||
}
|
||||
|
||||
func (p *Process) Cmdline() (string, error) {
|
||||
return p.CmdlineWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
|
||||
argv, err := p.CmdlineSlice()
|
||||
argv, err := p.CmdlineSliceWithContext(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -134,22 +104,9 @@ func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
|
|||
func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
|
||||
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) {
|
||||
return p, common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Status() (string, error) {
|
||||
return p.StatusWithContext(context.Background())
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
func (p *Process) Foreground() (bool, error) {
|
||||
return p.ForegroundWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
|
||||
// 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
|
||||
}
|
||||
func (p *Process) Uids() ([]int32, error) {
|
||||
return p.UidsWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -206,9 +157,6 @@ func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
|
|||
|
||||
return uids, nil
|
||||
}
|
||||
func (p *Process) Gids() ([]int32, error) {
|
||||
return p.GidsWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -221,16 +169,19 @@ func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
|
|||
|
||||
return gids, nil
|
||||
}
|
||||
|
||||
func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) {
|
||||
k, err := p.getKProc()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return k.Groups, nil
|
||||
}
|
||||
func (p *Process) Terminal() (string, error) {
|
||||
return p.TerminalWithContext(context.Background())
|
||||
groups := make([]int32, k.Ngroups)
|
||||
for i := int16(0); i < k.Ngroups; i++ {
|
||||
groups[i] = int32(k.Groups[i])
|
||||
}
|
||||
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
func (p *Process) Nice() (int32, error) {
|
||||
return p.NiceWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -259,32 +207,6 @@ func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
|
|||
}
|
||||
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) {
|
||||
k, err := p.getKProc()
|
||||
|
@ -296,39 +218,11 @@ func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, e
|
|||
WriteCount: uint64(k.Uru_oublock),
|
||||
}, 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) {
|
||||
/* not supported, just return 1 */
|
||||
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) {
|
||||
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,
|
||||
}, 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) {
|
||||
k, err := p.getKProc()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pageSize, err := mem.GetPageSize()
|
||||
pageSize, err := mem.GetPageSizeWithContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -368,25 +252,6 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e
|
|||
uint64(k.Vm_ssize),
|
||||
}, 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) {
|
||||
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))
|
||||
for _, pid := range pids {
|
||||
np, err := NewProcess(pid)
|
||||
np, err := NewProcessWithContext(ctx, pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -404,55 +269,18 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
|
|||
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) {
|
||||
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) {
|
||||
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
|
||||
}
|
||||
|
||||
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) {
|
||||
results := []*Process{}
|
||||
|
||||
buf, length, err := CallKernProcSyscall(KernProcAll, 0)
|
||||
buf, length, err := callKernProcSyscall(KernProcAll, 0)
|
||||
|
||||
if err != nil {
|
||||
return results, err
|
||||
|
@ -468,7 +296,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
|||
if err != nil {
|
||||
continue
|
||||
}
|
||||
p, err := NewProcess(int32(k.Pid))
|
||||
p, err := NewProcessWithContext(ctx, int32(k.Pid))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@ -479,19 +307,8 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
|||
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) {
|
||||
return p.getKProcWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) getKProcWithContext(ctx context.Context) (*KinfoProc, error) {
|
||||
buf, length, err := CallKernProcSyscall(KernProcPID, p.Pid)
|
||||
buf, length, err := callKernProcSyscall(KernProcPID, p.Pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -506,11 +323,7 @@ func (p *Process) getKProcWithContext(ctx context.Context) (*KinfoProc, error) {
|
|||
return &k, nil
|
||||
}
|
||||
|
||||
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) {
|
||||
func callKernProcSyscall(op int32, arg int32) ([]byte, uint64, error) {
|
||||
mib := []int32{CTLKern, KernProc, op, arg, sizeOfKinfoProc, 0}
|
||||
mibptr := unsafe.Pointer(&mib[0])
|
||||
miblen := uint64(len(mib))
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -114,12 +114,6 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
|
|||
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 {
|
||||
process, err := os.FindProcess(int(p.Pid))
|
||||
if err != nil {
|
||||
|
@ -134,49 +128,24 @@ func (p *Process) SendSignalWithContext(ctx context.Context, sig syscall.Signal)
|
|||
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 {
|
||||
return p.SendSignal(unix.SIGSTOP)
|
||||
}
|
||||
|
||||
// Resume sends SIGCONT to the process.
|
||||
func (p *Process) Resume() error {
|
||||
return p.ResumeWithContext(context.Background())
|
||||
return p.SendSignalWithContext(ctx, unix.SIGSTOP)
|
||||
}
|
||||
|
||||
func (p *Process) ResumeWithContext(ctx context.Context) error {
|
||||
return p.SendSignal(unix.SIGCONT)
|
||||
}
|
||||
|
||||
// Terminate sends SIGTERM to the process.
|
||||
func (p *Process) Terminate() error {
|
||||
return p.TerminateWithContext(context.Background())
|
||||
return p.SendSignalWithContext(ctx, unix.SIGCONT)
|
||||
}
|
||||
|
||||
func (p *Process) TerminateWithContext(ctx context.Context) error {
|
||||
return p.SendSignal(unix.SIGTERM)
|
||||
}
|
||||
|
||||
// Kill sends SIGKILL to the process.
|
||||
func (p *Process) Kill() error {
|
||||
return p.KillWithContext(context.Background())
|
||||
return p.SendSignalWithContext(ctx, unix.SIGTERM)
|
||||
}
|
||||
|
||||
func (p *Process) KillWithContext(ctx context.Context) error {
|
||||
return p.SendSignal(unix.SIGKILL)
|
||||
}
|
||||
|
||||
// Username returns a username of the process.
|
||||
func (p *Process) Username() (string, error) {
|
||||
return p.UsernameWithContext(context.Background())
|
||||
return p.SendSignalWithContext(ctx, unix.SIGKILL)
|
||||
}
|
||||
|
||||
func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
|
||||
uids, err := p.Uids()
|
||||
uids, err := p.UidsWithContext(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
@ -235,38 +235,43 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
|
|||
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) {
|
||||
// if cached already, return from cache
|
||||
cachedPpid := p.getPpid()
|
||||
if cachedPpid != 0 {
|
||||
return cachedPpid, nil
|
||||
}
|
||||
|
||||
ppid, _, _, err := getFromSnapProcess(p.Pid)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// no errors and not cached already, so cache it
|
||||
p.setPpid(ppid)
|
||||
|
||||
return ppid, nil
|
||||
}
|
||||
|
||||
func (p *Process) Name() (string, error) {
|
||||
return p.NameWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
|
||||
_, _, name, err := getFromSnapProcess(p.Pid)
|
||||
ppid, _, name, err := getFromSnapProcess(p.Pid)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
func (p *Process) Tgid() (int32, error) {
|
||||
func (p *Process) TgidWithContext(ctx context.Context) (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) {
|
||||
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(p.Pid))
|
||||
if err != nil {
|
||||
|
@ -294,10 +299,6 @@ func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
|
|||
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) {
|
||||
cmdline, err := getProcessCommandLine(p.Pid)
|
||||
if err != nil {
|
||||
|
@ -306,13 +307,6 @@ func (p *Process) CmdlineWithContext(_ context.Context) (string, error) {
|
|||
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) {
|
||||
cmdline, err := p.CmdlineWithContext(ctx)
|
||||
if err != nil {
|
||||
|
@ -330,16 +324,9 @@ func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
|
|||
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) {
|
||||
return "", common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Parent() (*Process, error) {
|
||||
return p.ParentWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
|
||||
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 NewProcess(ppid)
|
||||
}
|
||||
func (p *Process) Status() (string, error) {
|
||||
return p.StatusWithContext(context.Background())
|
||||
return NewProcessWithContext(ctx, ppid)
|
||||
}
|
||||
|
||||
func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
|
||||
return "", common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) Foreground() (bool, error) {
|
||||
return p.ForegroundWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
|
||||
return false, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) Username() (string, error) {
|
||||
return p.UsernameWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
|
||||
pid := p.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
|
||||
}
|
||||
|
||||
func (p *Process) Uids() ([]int32, error) {
|
||||
return p.UidsWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
|
||||
var uids []int32
|
||||
|
||||
return uids, common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Gids() ([]int32, error) {
|
||||
return p.GidsWithContext(context.Background())
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
|
||||
var gids []int32
|
||||
return gids, common.ErrNotImplementedError
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) {
|
||||
var groups []int32
|
||||
return groups, common.ErrNotImplementedError
|
||||
}
|
||||
func (p *Process) Terminal() (string, error) {
|
||||
return p.TerminalWithContext(context.Background())
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
|
||||
|
@ -434,11 +396,6 @@ var priorityClasses = map[int]int32{
|
|||
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) {
|
||||
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(p.Pid))
|
||||
if err != nil {
|
||||
|
@ -455,34 +412,17 @@ func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
|
|||
}
|
||||
return priority, 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)
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
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())
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
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) {
|
||||
_, ret, _, err := getFromSnapProcess(p.Pid)
|
||||
ppid, ret, _, err := getFromSnapProcess(p.Pid)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
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())
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
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,
|
||||
}, 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) {
|
||||
mem, err := getMemoryInfo(p.Pid)
|
||||
|
@ -589,26 +514,15 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e
|
|||
|
||||
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) {
|
||||
out := []*Process{}
|
||||
snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, uint32(0))
|
||||
|
@ -623,7 +537,7 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
|
|||
}
|
||||
for {
|
||||
if pe32.ParentProcessID == uint32(p.Pid) {
|
||||
p, err := NewProcess(int32(pe32.ProcessID))
|
||||
p, err := NewProcessWithContext(ctx, int32(pe32.ProcessID))
|
||||
if err == nil {
|
||||
out = append(out, p)
|
||||
}
|
||||
|
@ -635,59 +549,30 @@ func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
|
|||
return out, 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) {
|
||||
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) {
|
||||
return []net.ConnectionStat{}, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
|
||||
return p.NetIOCountersWithContext(context.Background(), pernic)
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
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
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) SendSignal(sig windows.Signal) error {
|
||||
return p.SendSignalWithContext(context.Background(), sig)
|
||||
}
|
||||
|
||||
func (p *Process) SendSignalWithContext(ctx context.Context, sig windows.Signal) error {
|
||||
func (p *Process) SendSignalWithContext(ctx context.Context, sig syscall.Signal) error {
|
||||
return common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
func (p *Process) Suspend() error {
|
||||
return p.SuspendWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) SuspendWithContext(ctx context.Context) error {
|
||||
c, err := windows.OpenProcess(windows.PROCESS_SUSPEND_RESUME, false, uint32(p.Pid))
|
||||
if err != nil {
|
||||
|
@ -695,7 +580,7 @@ func (p *Process) SuspendWithContext(ctx context.Context) error {
|
|||
}
|
||||
defer windows.CloseHandle(c)
|
||||
|
||||
r1, _, _ := procNtSuspendProcess.Call(uintptr(unsafe.Pointer(c)))
|
||||
r1, _, _ := procNtSuspendProcess.Call(uintptr(c))
|
||||
if r1 != 0 {
|
||||
// See https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
|
||||
return fmt.Errorf("NtStatus='0x%.8X'", r1)
|
||||
|
@ -704,10 +589,6 @@ func (p *Process) SuspendWithContext(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Process) Resume() error {
|
||||
return p.ResumeWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) ResumeWithContext(ctx context.Context) error {
|
||||
c, err := windows.OpenProcess(windows.PROCESS_SUSPEND_RESUME, false, uint32(p.Pid))
|
||||
if err != nil {
|
||||
|
@ -715,7 +596,7 @@ func (p *Process) ResumeWithContext(ctx context.Context) error {
|
|||
}
|
||||
defer windows.CloseHandle(c)
|
||||
|
||||
r1, _, _ := procNtResumeProcess.Call(uintptr(unsafe.Pointer(c)))
|
||||
r1, _, _ := procNtResumeProcess.Call(uintptr(c))
|
||||
if r1 != 0 {
|
||||
// See https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
|
||||
return fmt.Errorf("NtStatus='0x%.8X'", r1)
|
||||
|
@ -724,10 +605,6 @@ func (p *Process) ResumeWithContext(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Process) Terminate() error {
|
||||
return p.TerminateWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) TerminateWithContext(ctx context.Context) error {
|
||||
proc, err := windows.OpenProcess(windows.PROCESS_TERMINATE, false, uint32(p.Pid))
|
||||
if err != nil {
|
||||
|
@ -738,15 +615,26 @@ func (p *Process) TerminateWithContext(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (p *Process) Kill() error {
|
||||
return p.KillWithContext(context.Background())
|
||||
}
|
||||
|
||||
func (p *Process) KillWithContext(ctx context.Context) error {
|
||||
process := os.Process{Pid: int(p.Pid)}
|
||||
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) {
|
||||
snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, uint32(pid))
|
||||
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)
|
||||
}
|
||||
|
||||
// Get processes
|
||||
func Processes() ([]*Process, error) {
|
||||
return ProcessesWithContext(context.Background())
|
||||
}
|
||||
|
||||
func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
||||
out := []*Process{}
|
||||
|
||||
|
@ -784,7 +667,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
|||
}
|
||||
|
||||
for _, pid := range pids {
|
||||
p, err := NewProcess(pid)
|
||||
p, err := NewProcessWithContext(ctx, pid)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@ -1002,7 +885,7 @@ func convertUTF16ToString(src []byte) string {
|
|||
|
||||
srcIdx := 0
|
||||
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
|
||||
}
|
||||
return syscall.UTF16ToString(codePoints)
|
||||
|
|
|
@ -332,7 +332,7 @@ github.com/rcrowley/go-metrics
|
|||
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
|
||||
# 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/internal/common
|
||||
github.com/shirou/gopsutil/mem
|
||||
|
|
Loading…
Reference in New Issue