Update gopsutil & x/sys libraries (#10889)

This commit is contained in:
Michael Golowka 2021-02-10 14:33:11 -07:00 committed by GitHub
parent 85c1ae1002
commit d22c6f9a7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
208 changed files with 9598 additions and 6937 deletions

4
go.mod
View File

@ -139,7 +139,7 @@ require (
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da
github.com/sasha-s/go-deadlock v0.2.0
github.com/sethvargo/go-limiter v0.3.0
github.com/shirou/gopsutil v2.20.9+incompatible
github.com/shirou/gopsutil v3.21.1+incompatible
github.com/stretchr/testify v1.6.1
github.com/tidwall/pretty v1.0.1 // indirect
github.com/ulikunitz/xz v0.5.7 // indirect
@ -153,7 +153,7 @@ require (
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0
golang.org/x/net v0.0.0-20201002202402-0a1ea396d57c
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
golang.org/x/tools v0.0.0-20200521155704-91d71f6c2f04
google.golang.org/api v0.29.0
google.golang.org/grpc v1.29.1

6
go.sum
View File

@ -1047,8 +1047,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUt
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sethvargo/go-limiter v0.3.0 h1:yRMc+Qs2yqw6YJp6UxrO2iUs6DOSq4zcnljbB7/rMns=
github.com/sethvargo/go-limiter v0.3.0/go.mod h1:C0kbSFbiriE5k2FFOe18M1YZbAR2Fiwf72uGu0CXCcU=
github.com/shirou/gopsutil v2.20.9+incompatible h1:msXs2frUV+O/JLva9EDLpuJ84PrFsdCTCQex8PUdtkQ=
github.com/shirou/gopsutil v2.20.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v3.21.1+incompatible h1:2LwXWdbjXwyDgq26Yy/OT4xozlpmssQfy/rtfhWb0bY=
github.com/shirou/gopsutil v3.21.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
@ -1365,6 +1365,8 @@ golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -313,19 +313,25 @@ func CountsWithContext(ctx context.Context, logical bool) (int, error) {
return ret, nil
}
// physical cores
// https://github.com/giampaolo/psutil/blob/122174a10b75c9beebe15f6c07dcf3afbe3b120d/psutil/_pslinux.py#L621-L629
// https://github.com/giampaolo/psutil/blob/8415355c8badc9c94418b19bdf26e622f06f0cce/psutil/_pslinux.py#L615-L628
var threadSiblingsLists = make(map[string]bool)
if files, err := filepath.Glob(common.HostSys("devices/system/cpu/cpu[0-9]*/topology/thread_siblings_list")); err == nil {
for _, file := range files {
lines, err := common.ReadLines(file)
if err != nil || len(lines) != 1 {
continue
// 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
}
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

View File

@ -1,6 +1,7 @@
package disk
import (
"context"
"encoding/json"
"github.com/shirou/gopsutil/internal/common"
@ -59,3 +60,23 @@ func (d IOCountersStat) String() string {
s, _ := json.Marshal(d)
return string(s)
}
// Usage returns a file system usage. path is a filesystem path such
// as "/", not device file path like "/dev/vda1". If you want to use
// a return value of disk.Partitions, use "Mountpoint" not "Device".
func Usage(path string) (*UsageStat, error) {
return UsageWithContext(context.Background(), path)
}
// Partitions returns disk partitions. If all is false, returns
// physical devices only (e.g. hard disks, cd-rom drives, USB keys)
// and ignore all others (e.g. memory partitions such as /dev/shm)
//
// 'all' argument is ignored for BSD, see: https://github.com/giampaolo/psutil/issues/906
func Partitions(all bool) ([]PartitionStat, error) {
return PartitionsWithContext(context.Background(), all)
}
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), names...)
}

View File

@ -4,16 +4,13 @@ package disk
import (
"context"
"path"
"github.com/shirou/gopsutil/internal/common"
"golang.org/x/sys/unix"
)
func Partitions(all bool) ([]PartitionStat, error) {
return PartitionsWithContext(context.Background(), all)
}
// PartitionsWithContext returns disk partition.
// 'all' argument is ignored, see: https://github.com/giampaolo/psutil/issues/906
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
var ret []PartitionStat
@ -64,16 +61,11 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
opts += ",nodev"
}
d := PartitionStat{
Device: common.IntToString(stat.Mntfromname[:]),
Mountpoint: common.IntToString(stat.Mntonname[:]),
Fstype: common.IntToString(stat.Fstypename[:]),
Device: common.ByteToString(stat.Mntfromname[:]),
Mountpoint: common.ByteToString(stat.Mntonname[:]),
Fstype: common.ByteToString(stat.Fstypename[:]),
Opts: opts,
}
if all == false {
if !path.IsAbs(d.Device) || !common.PathExists(d.Device) {
continue
}
}
ret = append(ret, d)
}
@ -82,5 +74,5 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
}
func getFsType(stat unix.Statfs_t) string {
return common.IntToString(stat.Fstypename[:])
return common.ByteToString(stat.Fstypename[:])
}

View File

@ -17,10 +17,6 @@ import (
"github.com/shirou/gopsutil/internal/common"
)
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), names...)
}
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
var buf [C.NDRIVE]C.DriveStats
n, err := C.readdrivestat(&buf[0], C.int(len(buf)))

View File

@ -9,10 +9,6 @@ import (
"github.com/shirou/gopsutil/internal/common"
)
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), names...)
}
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
return nil, common.ErrNotImplementedError
}

View File

@ -8,26 +8,14 @@ import (
"github.com/shirou/gopsutil/internal/common"
)
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), names...)
}
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
return nil, common.ErrNotImplementedError
}
func Partitions(all bool) ([]PartitionStat, error) {
return PartitionsWithContext(context.Background(), all)
}
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
return []PartitionStat{}, common.ErrNotImplementedError
}
func Usage(path string) (*UsageStat, error) {
return UsageWithContext(context.Background(), path)
}
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
return nil, common.ErrNotImplementedError
}

View File

@ -6,7 +6,6 @@ import (
"bytes"
"context"
"encoding/binary"
"path"
"strconv"
"golang.org/x/sys/unix"
@ -14,10 +13,8 @@ import (
"github.com/shirou/gopsutil/internal/common"
)
func Partitions(all bool) ([]PartitionStat, error) {
return PartitionsWithContext(context.Background(), all)
}
// PartitionsWithContext returns disk partition.
// 'all' argument is ignored, see: https://github.com/giampaolo/psutil/issues/906
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
var ret []PartitionStat
@ -89,11 +86,6 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
Fstype: common.ByteToString(stat.Fstypename[:]),
Opts: opts,
}
if all == false {
if !path.IsAbs(d.Device) || !common.PathExists(d.Device) {
continue
}
}
ret = append(ret, d)
}
@ -101,10 +93,6 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
return ret, nil
}
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), names...)
}
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
// statinfo->devinfo->devstat
// /usr/include/devinfo.h

View File

@ -218,13 +218,6 @@ var fsTypeMap = map[int64]string{
ZFS_SUPER_MAGIC: "zfs", /* 0x2FC12FC1 local */
}
// Partitions returns disk partitions. If all is false, returns
// physical devices only (e.g. hard disks, cd-rom drives, USB keys)
// and ignore all others (e.g. memory partitions such as /dev/shm)
func Partitions(all bool) ([]PartitionStat, error) {
return PartitionsWithContext(context.Background(), all)
}
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
useMounts := false
@ -283,6 +276,14 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
mountPoint := fields[4]
mountOpts := fields[5]
if rootDir := fields[3]; rootDir != "" && rootDir != "/" {
if len(mountOpts) == 0 {
mountOpts = "bind"
} else {
mountOpts = "bind," + mountOpts
}
}
fields = strings.Fields(parts[1])
fstype := fields[0]
device := fields[1]
@ -346,10 +347,6 @@ func getFileSystems() ([]string, error) {
return ret, nil
}
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), names...)
}
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
filename := common.HostProc("diskstats")
lines, err := common.ReadLines(filename)

View File

@ -6,16 +6,11 @@ import (
"bytes"
"context"
"encoding/binary"
"path"
"github.com/shirou/gopsutil/internal/common"
"golang.org/x/sys/unix"
)
func Partitions(all bool) ([]PartitionStat, error) {
return PartitionsWithContext(context.Background(), all)
}
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
var ret []PartitionStat
@ -66,11 +61,6 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
Fstype: common.IntToString(stat.F_fstypename[:]),
Opts: opts,
}
if all == false {
if !path.IsAbs(d.Device) || !common.PathExists(d.Device) {
continue
}
}
ret = append(ret, d)
}
@ -78,10 +68,6 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
return ret, nil
}
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), names...)
}
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
ret := make(map[string]IOCountersStat)
@ -134,10 +120,6 @@ func parseDiskstats(buf []byte) (Diskstats, error) {
return ds, nil
}
func Usage(path string) (*UsageStat, error) {
return UsageWithContext(context.Background(), path)
}
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
stat := unix.Statfs_t{}
err := unix.Statfs(path, &stat)

View File

@ -38,10 +38,6 @@ var (
}
)
func Partitions(all bool) ([]PartitionStat, error) {
return PartitionsWithContext(context.Background(), all)
}
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
ret := make([]PartitionStat, 0, _DEFAULT_NUM_MOUNTS)
@ -83,18 +79,10 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
return ret, err
}
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), names...)
}
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
return nil, common.ErrNotImplementedError
}
func Usage(path string) (*UsageStat, error) {
return UsageWithContext(context.Background(), path)
}
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
statvfs := unix.Statvfs_t{}
if err := unix.Statvfs(path, &statvfs); err != nil {

View File

@ -9,13 +9,6 @@ import (
"golang.org/x/sys/unix"
)
// Usage returns a file system usage. path is a filesystem path such
// as "/", not device file path like "/dev/vda1". If you want to use
// a return value of disk.Partitions, use "Mountpoint" not "Device".
func Usage(path string) (*UsageStat, error) {
return UsageWithContext(context.Background(), path)
}
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
stat := unix.Statfs_t{}
err := unix.Statfs(path, &stat)

View File

@ -43,10 +43,6 @@ type diskPerformance struct {
alignmentPadding uint32 // necessary for 32bit support, see https://github.com/elastic/beats/pull/16553
}
func Usage(path string) (*UsageStat, error) {
return UsageWithContext(context.Background(), path)
}
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
lpFreeBytesAvailable := int64(0)
lpTotalNumberOfBytes := int64(0)
@ -73,10 +69,6 @@ func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
return ret, nil
}
func Partitions(all bool) ([]PartitionStat, error) {
return PartitionsWithContext(context.Background(), all)
}
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
var ret []PartitionStat
lpBuffer := make([]byte, 254)
@ -139,10 +131,6 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
return ret, nil
}
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), names...)
}
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
// https://github.com/giampaolo/psutil/blob/544e9daa4f66a9f80d7bf6c7886d693ee42f0a13/psutil/arch/windows/disk.c#L83
drivemap := make(map[string]IOCountersStat, 0)
@ -155,7 +143,7 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
}
for _, v := range lpBuffer[:lpBufferLen] {
if 'A' <= v && v <= 'Z' {
path := string(v) + ":"
path := string(rune(v)) + ":"
typepath, _ := windows.UTF16PtrFromString(path)
typeret := windows.GetDriveType(typepath)
if typeret == 0 {

View File

@ -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 {

View File

@ -10,6 +10,7 @@ import (
"path/filepath"
"strconv"
"strings"
"sync"
"time"
)
@ -110,16 +111,24 @@ func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
var virtualizationCache map[string]string
// 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, role string
// if cached already, return from cache
if virtualizationCache != nil {
return virtualizationCache["system"], virtualizationCache["role"], nil
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
}
var system string
var role string
cachedVirtMutex.RUnlock()
filename := HostProc("xen")
if PathExists(filename) {
@ -238,13 +247,17 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) {
role = "host"
}
}
// before returning for the first time, cache the system and role
virtualizationCache = map[string]string{
"system": system,
"role": role,
}
cachedVirtOnce.Do(func() {
cachedVirtMutex.Lock()
defer cachedVirtMutex.Unlock()
cachedVirtMap = map[string]string{
"system": system,
"role": role,
}
})
return system, role, nil
}

View File

@ -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 {

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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) {

View File

@ -63,7 +63,7 @@ func ConnectionsPidWithContext(ctx context.Context, kind string, pid int32) ([]C
case "udp":
args = append(args, "udp")
case "udp4":
args = append(args, "6udp")
args = append(args, "4udp")
case "udp6":
args = append(args, "6udp")
case "unix":

View File

@ -547,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)

View File

@ -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
}
@ -204,7 +221,7 @@ func (p *Process) PercentWithContext(ctx context.Context, interval time.Duration
if err := common.Sleep(ctx, interval); err != nil {
return 0, err
}
cpuTimes, err = p.Times()
cpuTimes, err = p.TimesWithContext(ctx)
now = time.Now()
if err != nil {
return 0, err
@ -236,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
}
@ -276,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
}
@ -297,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
}
@ -320,3 +337,208 @@ func (p *Process) CPUPercentWithContext(ctx context.Context) (float64, error) {
func (p *Process) Groups() ([]int32, error) {
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 and VMS.
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
// MemoryInfoEx returns platform-specific process memory information.
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
// PageFaultsInfo returns the process's page fault counters.
func (p *Process) PageFaults() (*PageFaultsStat, error) {
return p.PageFaultsWithContext(context.Background())
}
// Children returns a slice of Process of the process.
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
// OpenFiles returns a slice of OpenFilesStat opend by the process.
// OpenFilesStat includes a file path and file descriptor.
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
// Connections returns a slice of net.ConnectionStat used by the process.
// This returns all kind of the connection. This means TCP, UDP or UNIX.
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
}
// Connections returns a slice of net.ConnectionStat used by the process at most `max`.
func (p *Process) ConnectionsMax(max int) ([]net.ConnectionStat, error) {
return p.ConnectionsMaxWithContext(context.Background(), max)
}
// NetIOCounters returns NetIOCounters of the process.
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
}
// MemoryMaps get memory maps from /proc/(pid)/smaps
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
}
// Tgid returns thread group id of the process.
func (p *Process) Tgid() (int32, error) {
return p.TgidWithContext(context.Background())
}
// SendSignal sends a unix.Signal to the process.
func (p *Process) SendSignal(sig syscall.Signal) error {
return p.SendSignalWithContext(context.Background(), sig)
}
// Suspend sends SIGSTOP to the process.
func (p *Process) Suspend() error {
return p.SuspendWithContext(context.Background())
}
// Resume sends SIGCONT to the process.
func (p *Process) Resume() error {
return p.ResumeWithContext(context.Background())
}
// Terminate sends SIGTERM to the process.
func (p *Process) Terminate() error {
return p.TerminateWithContext(context.Background())
}
// Kill sends SIGKILL to the process.
func (p *Process) Kill() error {
return p.KillWithContext(context.Background())
}
// Username returns a username of the process.
func (p *Process) Username() (string, error) {
return p.UsernameWithContext(context.Background())
}

View File

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

View File

@ -3,16 +3,13 @@
package process
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(
202, // unix.SYS___SYSCTL https://github.com/golang/sys/blob/76b94024e4b621e672466e8db3d7f084e7ddcad2/unix/zsysnum_darwin_amd64.go#L146
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 {

View File

@ -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

View File

@ -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)

View File

@ -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) {
@ -572,9 +399,9 @@ func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]M
lines := strings.Split(string(contents), "\n")
// function of parsing a block
getBlock := func(first_line []string, block []string) (MemoryMapsStat, error) {
getBlock := func(firstLine []string, block []string) (MemoryMapsStat, error) {
m := MemoryMapsStat{}
m.Path = first_line[len(first_line)-1]
m.Path = firstLine[len(firstLine)-1]
for _, line := range block {
if strings.Contains(line, "VmFlags") {
@ -617,13 +444,15 @@ func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]M
return m, nil
}
blocks := make([]string, 16)
for _, line := range lines {
var firstLine []string
blocks := make([]string, 0, 16)
for i, line := range lines {
fields := strings.Fields(line)
if len(fields) > 0 && !strings.HasSuffix(fields[0], ":") {
if (len(fields) > 0 && !strings.HasSuffix(fields[0], ":")) || i == len(lines)-1 {
// new block section
if len(blocks) > 0 {
g, err := getBlock(fields, blocks)
if len(firstLine) > 0 && len(blocks) > 0 {
g, err := getBlock(firstLine, blocks)
if err != nil {
return &ret, err
}
@ -643,7 +472,8 @@ func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]M
}
}
// starts new block
blocks = make([]string, 16)
blocks = make([]string, 0, 16)
firstLine = fields
} else {
blocks = append(blocks, line)
}
@ -1181,7 +1011,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 +1079,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 +1088,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
}

View File

@ -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))

View File

@ -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
}

View File

@ -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
}

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -39,31 +39,34 @@ func initOptions() {
func archInit() {
switch runtime.GOOS {
case "android", "darwin", "ios", "netbsd":
// Android and iOS don't seem to allow reading these registers.
//
// NetBSD:
// ID_AA64ISAR0_EL1 is a privileged register and cannot be read from EL0.
// It can be read via sysctl(3). Example for future implementers:
// https://nxr.netbsd.org/xref/src/usr.sbin/cpuctl/arch/aarch64.c
//
// Fake the minimal features expected by
// TestARM64minimalFeatures.
ARM64.HasASIMD = true
ARM64.HasFP = true
case "linux":
case "freebsd":
readARM64Registers()
case "linux", "netbsd":
doinit()
default:
readARM64Registers()
// Most platforms don't seem to allow reading these registers.
//
// OpenBSD:
// See https://golang.org/issue/31746
setMinimalFeatures()
}
}
// setMinimalFeatures fakes the minimal ARM64 features expected by
// TestARM64minimalFeatures.
func setMinimalFeatures() {
ARM64.HasASIMD = true
ARM64.HasFP = true
}
func readARM64Registers() {
Initialized = true
// ID_AA64ISAR0_EL1
isar0 := getisar0()
parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0())
}
func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) {
// ID_AA64ISAR0_EL1
switch extractBits(isar0, 4, 7) {
case 1:
ARM64.HasAES = true
@ -121,8 +124,6 @@ func readARM64Registers() {
}
// ID_AA64ISAR1_EL1
isar1 := getisar1()
switch extractBits(isar1, 0, 3) {
case 1:
ARM64.HasDCPOP = true
@ -144,8 +145,6 @@ func readARM64Registers() {
}
// ID_AA64PFR0_EL1
pfr0 := getpfr0()
switch extractBits(pfr0, 16, 19) {
case 0:
ARM64.HasFP = true

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
package cpu

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
package cpu

View File

@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// +build 386 amd64 amd64p32
// +build !gccgo
// +build gc
package cpu

View File

@ -17,86 +17,7 @@ const (
hwcap_VXE = 8192
)
// bitIsSet reports whether the bit at index is set. The bit index
// is in big endian order, so bit index 0 is the leftmost bit.
func bitIsSet(bits []uint64, index uint) bool {
return bits[index/64]&((1<<63)>>(index%64)) != 0
}
// function is the code for the named cryptographic function.
type function uint8
const (
// KM{,A,C,CTR} function codes
aes128 function = 18 // AES-128
aes192 function = 19 // AES-192
aes256 function = 20 // AES-256
// K{I,L}MD function codes
sha1 function = 1 // SHA-1
sha256 function = 2 // SHA-256
sha512 function = 3 // SHA-512
sha3_224 function = 32 // SHA3-224
sha3_256 function = 33 // SHA3-256
sha3_384 function = 34 // SHA3-384
sha3_512 function = 35 // SHA3-512
shake128 function = 36 // SHAKE-128
shake256 function = 37 // SHAKE-256
// KLMD function codes
ghash function = 65 // GHASH
)
// queryResult contains the result of a Query function
// call. Bits are numbered in big endian order so the
// leftmost bit (the MSB) is at index 0.
type queryResult struct {
bits [2]uint64
}
// Has reports whether the given functions are present.
func (q *queryResult) Has(fns ...function) bool {
if len(fns) == 0 {
panic("no function codes provided")
}
for _, f := range fns {
if !bitIsSet(q.bits[:], uint(f)) {
return false
}
}
return true
}
// facility is a bit index for the named facility.
type facility uint8
const (
// cryptography facilities
msa4 facility = 77 // message-security-assist extension 4
msa8 facility = 146 // message-security-assist extension 8
)
// facilityList contains the result of an STFLE call.
// Bits are numbered in big endian order so the
// leftmost bit (the MSB) is at index 0.
type facilityList struct {
bits [4]uint64
}
// Has reports whether the given facilities are present.
func (s *facilityList) Has(fs ...facility) bool {
if len(fs) == 0 {
panic("no facility bits provided")
}
for _, f := range fs {
if !bitIsSet(s.bits[:], uint(f)) {
return false
}
}
return true
}
func doinit() {
func initS390Xbase() {
// test HWCAP bit vector
has := func(featureMask uint) bool {
return hwCap&featureMask == featureMask
@ -116,44 +37,4 @@ func doinit() {
if S390X.HasVX {
S390X.HasVXE = has(hwcap_VXE)
}
// We need implementations of stfle, km and so on
// to detect cryptographic features.
if !haveAsmFunctions() {
return
}
// optional cryptographic functions
if S390X.HasMSA {
aes := []function{aes128, aes192, aes256}
// cipher message
km, kmc := kmQuery(), kmcQuery()
S390X.HasAES = km.Has(aes...)
S390X.HasAESCBC = kmc.Has(aes...)
if S390X.HasSTFLE {
facilities := stfle()
if facilities.Has(msa4) {
kmctr := kmctrQuery()
S390X.HasAESCTR = kmctr.Has(aes...)
}
if facilities.Has(msa8) {
kma := kmaQuery()
S390X.HasAESGCM = kma.Has(aes...)
}
}
// compute message digest
kimd := kimdQuery() // intermediate (no padding)
klmd := klmdQuery() // last (padding)
S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1)
S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256)
S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512)
S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist
sha3 := []function{
sha3_224, sha3_256, sha3_384, sha3_512,
shake128, shake256,
}
S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...)
}
}

173
vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go generated vendored Normal file
View File

@ -0,0 +1,173 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cpu
import (
"syscall"
"unsafe"
)
// Minimal copy of functionality from x/sys/unix so the cpu package can call
// sysctl without depending on x/sys/unix.
const (
_CTL_QUERY = -2
_SYSCTL_VERS_1 = 0x1000000
)
var _zero uintptr
func sysctl(mib []int32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
var _p0 unsafe.Pointer
if len(mib) > 0 {
_p0 = unsafe.Pointer(&mib[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
_, _, errno := syscall.Syscall6(
syscall.SYS___SYSCTL,
uintptr(_p0),
uintptr(len(mib)),
uintptr(unsafe.Pointer(old)),
uintptr(unsafe.Pointer(oldlen)),
uintptr(unsafe.Pointer(new)),
uintptr(newlen))
if errno != 0 {
return errno
}
return nil
}
type sysctlNode struct {
Flags uint32
Num int32
Name [32]int8
Ver uint32
__rsvd uint32
Un [16]byte
_sysctl_size [8]byte
_sysctl_func [8]byte
_sysctl_parent [8]byte
_sysctl_desc [8]byte
}
func sysctlNodes(mib []int32) ([]sysctlNode, error) {
var olen uintptr
// Get a list of all sysctl nodes below the given MIB by performing
// a sysctl for the given MIB with CTL_QUERY appended.
mib = append(mib, _CTL_QUERY)
qnode := sysctlNode{Flags: _SYSCTL_VERS_1}
qp := (*byte)(unsafe.Pointer(&qnode))
sz := unsafe.Sizeof(qnode)
if err := sysctl(mib, nil, &olen, qp, sz); err != nil {
return nil, err
}
// Now that we know the size, get the actual nodes.
nodes := make([]sysctlNode, olen/sz)
np := (*byte)(unsafe.Pointer(&nodes[0]))
if err := sysctl(mib, np, &olen, qp, sz); err != nil {
return nil, err
}
return nodes, nil
}
func nametomib(name string) ([]int32, error) {
// Split name into components.
var parts []string
last := 0
for i := 0; i < len(name); i++ {
if name[i] == '.' {
parts = append(parts, name[last:i])
last = i + 1
}
}
parts = append(parts, name[last:])
mib := []int32{}
// Discover the nodes and construct the MIB OID.
for partno, part := range parts {
nodes, err := sysctlNodes(mib)
if err != nil {
return nil, err
}
for _, node := range nodes {
n := make([]byte, 0)
for i := range node.Name {
if node.Name[i] != 0 {
n = append(n, byte(node.Name[i]))
}
}
if string(n) == part {
mib = append(mib, int32(node.Num))
break
}
}
if len(mib) != partno+1 {
return nil, err
}
}
return mib, nil
}
// aarch64SysctlCPUID is struct aarch64_sysctl_cpu_id from NetBSD's <aarch64/armreg.h>
type aarch64SysctlCPUID struct {
midr uint64 /* Main ID Register */
revidr uint64 /* Revision ID Register */
mpidr uint64 /* Multiprocessor Affinity Register */
aa64dfr0 uint64 /* A64 Debug Feature Register 0 */
aa64dfr1 uint64 /* A64 Debug Feature Register 1 */
aa64isar0 uint64 /* A64 Instruction Set Attribute Register 0 */
aa64isar1 uint64 /* A64 Instruction Set Attribute Register 1 */
aa64mmfr0 uint64 /* A64 Memory Model Feature Register 0 */
aa64mmfr1 uint64 /* A64 Memory Model Feature Register 1 */
aa64mmfr2 uint64 /* A64 Memory Model Feature Register 2 */
aa64pfr0 uint64 /* A64 Processor Feature Register 0 */
aa64pfr1 uint64 /* A64 Processor Feature Register 1 */
aa64zfr0 uint64 /* A64 SVE Feature ID Register 0 */
mvfr0 uint32 /* Media and VFP Feature Register 0 */
mvfr1 uint32 /* Media and VFP Feature Register 1 */
mvfr2 uint32 /* Media and VFP Feature Register 2 */
pad uint32
clidr uint64 /* Cache Level ID Register */
ctr uint64 /* Cache Type Register */
}
func sysctlCPUID(name string) (*aarch64SysctlCPUID, error) {
mib, err := nametomib(name)
if err != nil {
return nil, err
}
out := aarch64SysctlCPUID{}
n := unsafe.Sizeof(out)
_, _, errno := syscall.Syscall6(
syscall.SYS___SYSCTL,
uintptr(unsafe.Pointer(&mib[0])),
uintptr(len(mib)),
uintptr(unsafe.Pointer(&out)),
uintptr(unsafe.Pointer(&n)),
uintptr(0),
uintptr(0))
if errno != 0 {
return nil, errno
}
return &out, nil
}
func doinit() {
cpuid, err := sysctlCPUID("machdep.cpu0.cpu_id")
if err != nil {
setMinimalFeatures()
return
}
parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64pfr0)
Initialized = true
}

View File

@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !linux,arm64
// +build !linux,!netbsd
// +build arm64
package cpu

12
vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go generated vendored Normal file
View File

@ -0,0 +1,12 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !linux
// +build mips64 mips64le
package cpu
func archInit() {
Initialized = true
}

View File

@ -8,10 +8,10 @@ const cacheLineSize = 256
func initOptions() {
options = []option{
{Name: "zarch", Feature: &S390X.HasZARCH},
{Name: "stfle", Feature: &S390X.HasSTFLE},
{Name: "ldisp", Feature: &S390X.HasLDISP},
{Name: "eimm", Feature: &S390X.HasEIMM},
{Name: "zarch", Feature: &S390X.HasZARCH, Required: true},
{Name: "stfle", Feature: &S390X.HasSTFLE, Required: true},
{Name: "ldisp", Feature: &S390X.HasLDISP, Required: true},
{Name: "eimm", Feature: &S390X.HasEIMM, Required: true},
{Name: "dfp", Feature: &S390X.HasDFP},
{Name: "etf3eh", Feature: &S390X.HasETF3EH},
{Name: "msa", Feature: &S390X.HasMSA},
@ -28,3 +28,145 @@ func initOptions() {
{Name: "vxe", Feature: &S390X.HasVXE},
}
}
// bitIsSet reports whether the bit at index is set. The bit index
// is in big endian order, so bit index 0 is the leftmost bit.
func bitIsSet(bits []uint64, index uint) bool {
return bits[index/64]&((1<<63)>>(index%64)) != 0
}
// facility is a bit index for the named facility.
type facility uint8
const (
// mandatory facilities
zarch facility = 1 // z architecture mode is active
stflef facility = 7 // store-facility-list-extended
ldisp facility = 18 // long-displacement
eimm facility = 21 // extended-immediate
// miscellaneous facilities
dfp facility = 42 // decimal-floating-point
etf3eh facility = 30 // extended-translation 3 enhancement
// cryptography facilities
msa facility = 17 // message-security-assist
msa3 facility = 76 // message-security-assist extension 3
msa4 facility = 77 // message-security-assist extension 4
msa5 facility = 57 // message-security-assist extension 5
msa8 facility = 146 // message-security-assist extension 8
msa9 facility = 155 // message-security-assist extension 9
// vector facilities
vx facility = 129 // vector facility
vxe facility = 135 // vector-enhancements 1
vxe2 facility = 148 // vector-enhancements 2
)
// facilityList contains the result of an STFLE call.
// Bits are numbered in big endian order so the
// leftmost bit (the MSB) is at index 0.
type facilityList struct {
bits [4]uint64
}
// Has reports whether the given facilities are present.
func (s *facilityList) Has(fs ...facility) bool {
if len(fs) == 0 {
panic("no facility bits provided")
}
for _, f := range fs {
if !bitIsSet(s.bits[:], uint(f)) {
return false
}
}
return true
}
// function is the code for the named cryptographic function.
type function uint8
const (
// KM{,A,C,CTR} function codes
aes128 function = 18 // AES-128
aes192 function = 19 // AES-192
aes256 function = 20 // AES-256
// K{I,L}MD function codes
sha1 function = 1 // SHA-1
sha256 function = 2 // SHA-256
sha512 function = 3 // SHA-512
sha3_224 function = 32 // SHA3-224
sha3_256 function = 33 // SHA3-256
sha3_384 function = 34 // SHA3-384
sha3_512 function = 35 // SHA3-512
shake128 function = 36 // SHAKE-128
shake256 function = 37 // SHAKE-256
// KLMD function codes
ghash function = 65 // GHASH
)
// queryResult contains the result of a Query function
// call. Bits are numbered in big endian order so the
// leftmost bit (the MSB) is at index 0.
type queryResult struct {
bits [2]uint64
}
// Has reports whether the given functions are present.
func (q *queryResult) Has(fns ...function) bool {
if len(fns) == 0 {
panic("no function codes provided")
}
for _, f := range fns {
if !bitIsSet(q.bits[:], uint(f)) {
return false
}
}
return true
}
func doinit() {
initS390Xbase()
// We need implementations of stfle, km and so on
// to detect cryptographic features.
if !haveAsmFunctions() {
return
}
// optional cryptographic functions
if S390X.HasMSA {
aes := []function{aes128, aes192, aes256}
// cipher message
km, kmc := kmQuery(), kmcQuery()
S390X.HasAES = km.Has(aes...)
S390X.HasAESCBC = kmc.Has(aes...)
if S390X.HasSTFLE {
facilities := stfle()
if facilities.Has(msa4) {
kmctr := kmctrQuery()
S390X.HasAESCTR = kmctr.Has(aes...)
}
if facilities.Has(msa8) {
kma := kmaQuery()
S390X.HasAESGCM = kma.Has(aes...)
}
}
// compute message digest
kimd := kimdQuery() // intermediate (no padding)
klmd := klmdQuery() // last (padding)
S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1)
S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256)
S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512)
S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist
sha3 := []function{
sha3_224, sha3_256, sha3_384, sha3_512,
shake128, shake256,
}
S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...)
}
}

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// +build 386 amd64 amd64p32
// +build !gccgo
// +build gc
#include "textflag.h"

10
vendor/golang.org/x/sys/cpu/cpu_zos.go generated vendored Normal file
View File

@ -0,0 +1,10 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cpu
func archInit() {
doinit()
Initialized = true
}

25
vendor/golang.org/x/sys/cpu/cpu_zos_s390x.go generated vendored Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cpu
func initS390Xbase() {
// get the facilities list
facilities := stfle()
// mandatory
S390X.HasZARCH = facilities.Has(zarch)
S390X.HasSTFLE = facilities.Has(stflef)
S390X.HasLDISP = facilities.Has(ldisp)
S390X.HasEIMM = facilities.Has(eimm)
// optional
S390X.HasETF3EH = facilities.Has(etf3eh)
S390X.HasDFP = facilities.Has(dfp)
S390X.HasMSA = facilities.Has(msa)
S390X.HasVX = facilities.Has(vx)
if S390X.HasVX {
S390X.HasVXE = facilities.Has(vxe)
}
}

View File

@ -7,7 +7,7 @@
// (See golang.org/issue/32102)
// +build aix,ppc64
// +build !gccgo
// +build gc
package cpu

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
// +build arm,darwin
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
// +build arm64,darwin
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -4,7 +4,7 @@
// +build linux
// +build arm64
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -4,7 +4,7 @@
// +build linux
// +build mips64 mips64le
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -4,7 +4,7 @@
// +build linux
// +build mips mipsle
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -4,7 +4,7 @@
// +build linux
// +build ppc64 ppc64le
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build riscv64,!gccgo
// +build riscv64,gc
#include "textflag.h"

View File

@ -4,7 +4,7 @@
// +build s390x
// +build linux
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
// +build gc
#include "textflag.h"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// +build ppc64 s390x mips mips64
// +build armbe arm64be m68k mips mips64 mips64p32 ppc ppc64 s390 s390x shbe sparc sparc64
package unix

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// +build 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le riscv64
// +build 386 amd64 amd64p32 alpha arm arm64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh
package unix

View File

@ -1,9 +1,9 @@
// +build linux,386 linux,arm linux,mips linux,mipsle
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,386 linux,arm linux,mips linux,mipsle
package unix
func init() {

View File

@ -59,12 +59,14 @@ includes_Darwin='
#include <stdint.h>
#include <sys/attr.h>
#include <sys/clonefile.h>
#include <sys/kern_control.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/ptrace.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sys_domain.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
@ -94,6 +96,7 @@ includes_DragonFly='
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_clone.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
@ -201,6 +204,7 @@ struct ltchars {
#include <linux/devlink.h>
#include <linux/dm-ioctl.h>
#include <linux/errqueue.h>
#include <linux/ethtool_netlink.h>
#include <linux/falloc.h>
#include <linux/fanotify.h>
#include <linux/filter.h>
@ -222,6 +226,7 @@ struct ltchars {
#include <linux/kexec.h>
#include <linux/keyctl.h>
#include <linux/loop.h>
#include <linux/lwtunnel.h>
#include <linux/magic.h>
#include <linux/memfd.h>
#include <linux/module.h>
@ -230,6 +235,7 @@ struct ltchars {
#include <linux/net_namespace.h>
#include <linux/nsfs.h>
#include <linux/perf_event.h>
#include <linux/pps.h>
#include <linux/ptrace.h>
#include <linux/random.h>
#include <linux/reboot.h>
@ -372,6 +378,7 @@ includes_SunOS='
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/stat.h>
#include <sys/stream.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
@ -496,6 +503,7 @@ ccflags="$@"
$2 !~ "NLA_TYPE_MASK" &&
$2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ &&
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||
$2 ~ /^FIORDCHK$/ ||
$2 ~ /^SIOC/ ||
$2 ~ /^TIOC/ ||
$2 ~ /^TCGET/ ||
@ -516,6 +524,7 @@ ccflags="$@"
$2 ~ /^CAP_/ ||
$2 ~ /^CP_/ ||
$2 ~ /^CPUSTATES$/ ||
$2 ~ /^CTLIOCGINFO$/ ||
$2 ~ /^ALG_/ ||
$2 ~ /^FI(CLONE|DEDUPERANGE)/ ||
$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE)/ ||
@ -527,7 +536,7 @@ ccflags="$@"
$2 ~ /^RND/ ||
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
$2 ~ /^KEYCTL_/ ||
$2 ~ /^PERF_EVENT_IOC_/ ||
$2 ~ /^PERF_/ ||
$2 ~ /^SECCOMP_MODE_/ ||
$2 ~ /^SPLICE_/ ||
$2 ~ /^SYNC_FILE_RANGE_/ ||
@ -546,14 +555,17 @@ ccflags="$@"
$2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ ||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
$2 ~ /^FSOPT_/ ||
$2 ~ /^WDIOC_/ ||
$2 ~ /^WDIO[CFS]_/ ||
$2 ~ /^NFN/ ||
$2 ~ /^XDP_/ ||
$2 ~ /^RWF_/ ||
$2 ~ /^(HDIO|WIN|SMART)_/ ||
$2 ~ /^CRYPTO_/ ||
$2 ~ /^TIPC_/ ||
$2 !~ "DEVLINK_RELOAD_LIMITS_VALID_MASK" &&
$2 ~ /^DEVLINK_/ ||
$2 ~ /^ETHTOOL_/ ||
$2 ~ /^LWTUNNEL_IP/ ||
$2 !~ "WMESGLEN" &&
$2 ~ /^W[A-Z0-9]+$/ ||
$2 ~/^PPPIOC/ ||

11
vendor/golang.org/x/sys/unix/ptrace_darwin.go generated vendored Normal file
View File

@ -0,0 +1,11 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin,!ios
package unix
func ptrace(request int, pid int, addr uintptr, data uintptr) error {
return ptrace1(request, pid, addr, data)
}

11
vendor/golang.org/x/sys/unix/ptrace_ios.go generated vendored Normal file
View File

@ -0,0 +1,11 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ios
package unix
func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
return ENOTSUP
}

View File

@ -24,7 +24,13 @@
// holds a value of type syscall.Errno.
package unix // import "golang.org/x/sys/unix"
import "strings"
import (
"bytes"
"strings"
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
// ByteSliceFromString returns a NUL-terminated slice of bytes
// containing the text of s. If s contains a NUL byte at any
@ -49,5 +55,40 @@ func BytePtrFromString(s string) (*byte, error) {
return &a[0], nil
}
// ByteSliceToString returns a string form of the text represented by the slice s, with a terminating NUL and any
// bytes after the NUL removed.
func ByteSliceToString(s []byte) string {
if i := bytes.IndexByte(s, 0); i != -1 {
s = s[:i]
}
return string(s)
}
// BytePtrToString takes a pointer to a sequence of text and returns the corresponding string.
// If the pointer is nil, it returns the empty string. It assumes that the text sequence is terminated
// at a zero byte; if the zero byte is not present, the program may crash.
func BytePtrToString(p *byte) string {
if p == nil {
return ""
}
if *p == 0 {
return ""
}
// Find NUL terminator.
n := 0
for ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ {
ptr = unsafe.Pointer(uintptr(ptr) + 1)
}
var s []byte
h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
h.Data = unsafe.Pointer(p)
h.Len = n
h.Cap = n
return string(s)
}
// Single-word zero for use when we need a valid pointer to 0 bytes.
var _zero uintptr

View File

@ -19,6 +19,22 @@ import "unsafe"
* Wrapped
*/
func Access(path string, mode uint32) (err error) {
return Faccessat(AT_FDCWD, path, mode, 0)
}
func Chmod(path string, mode uint32) (err error) {
return Fchmodat(AT_FDCWD, path, mode, 0)
}
func Chown(path string, uid int, gid int) (err error) {
return Fchownat(AT_FDCWD, path, uid, gid, 0)
}
func Creat(path string, mode uint32) (fd int, err error) {
return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
}
//sys utimes(path string, times *[2]Timeval) (err error)
func Utimes(path string, tv []Timeval) error {
if len(tv) != 2 {

View File

@ -277,7 +277,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
}
return sa, nil
}
return nil, EAFNOSUPPORT
return anyToSockaddrGOOS(fd, rsa)
}
func Accept(fd int) (nfd int, sa Sockaddr, err error) {

View File

@ -26,7 +26,6 @@ func fdopendir(fd int) (dir uintptr, err error) {
func libc_fdopendir_trampoline()
//go:linkname libc_fdopendir libc_fdopendir
//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {

View File

@ -13,6 +13,7 @@
package unix
import (
"runtime"
"syscall"
"unsafe"
)
@ -30,10 +31,40 @@ type SockaddrDatalink struct {
raw RawSockaddrDatalink
}
// SockaddrCtl implements the Sockaddr interface for AF_SYSTEM type sockets.
type SockaddrCtl struct {
ID uint32
Unit uint32
raw RawSockaddrCtl
}
func (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Sc_len = SizeofSockaddrCtl
sa.raw.Sc_family = AF_SYSTEM
sa.raw.Ss_sysaddr = AF_SYS_CONTROL
sa.raw.Sc_id = sa.ID
sa.raw.Sc_unit = sa.Unit
return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil
}
func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family {
case AF_SYSTEM:
pp := (*RawSockaddrCtl)(unsafe.Pointer(rsa))
if pp.Ss_sysaddr == AF_SYS_CONTROL {
sa := new(SockaddrCtl)
sa.ID = pp.Sc_id
sa.Unit = pp.Sc_unit
return sa, nil
}
}
return nil, EAFNOSUPPORT
}
// Some external packages rely on SYS___SYSCTL being defined to implement their
// own sysctl wrappers. Provide it here, even though direct syscalls are no
// longer supported on darwin.
const SYS___SYSCTL = 202
const SYS___SYSCTL = SYS_SYSCTL
// Translate "kern.hostname" to []_C_int{0,1,2,3}.
func nametomib(name string) (mib []_C_int, err error) {
@ -88,13 +119,16 @@ type attrList struct {
Forkattr uint32
}
//sysnb pipe() (r int, w int, err error)
//sysnb pipe(p *[2]int32) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
p[0], p[1], err = pipe()
var x [2]int32
err = pipe(&x)
p[0] = int(x[0])
p[1] = int(x[1])
return
}
@ -257,6 +291,35 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig
//sys ioctl(fd int, req uint, arg uintptr) (err error)
func IoctlCtlInfo(fd int, ctlInfo *CtlInfo) error {
err := ioctl(fd, CTLIOCGINFO, uintptr(unsafe.Pointer(ctlInfo)))
runtime.KeepAlive(ctlInfo)
return err
}
// IfreqMTU is struct ifreq used to get or set a network device's MTU.
type IfreqMTU struct {
Name [IFNAMSIZ]byte
MTU int32
}
// IoctlGetIfreqMTU performs the SIOCGIFMTU ioctl operation on fd to get the MTU
// of the network device specified by ifname.
func IoctlGetIfreqMTU(fd int, ifname string) (*IfreqMTU, error) {
var ifreq IfreqMTU
copy(ifreq.Name[:], ifname)
err := ioctl(fd, SIOCGIFMTU, uintptr(unsafe.Pointer(&ifreq)))
return &ifreq, err
}
// IoctlSetIfreqMTU performs the SIOCSIFMTU ioctl operation on fd to set the MTU
// of the network device specified by ifreq.Name.
func IoctlSetIfreqMTU(fd int, ifreq *IfreqMTU) error {
err := ioctl(fd, SIOCSIFMTU, uintptr(unsafe.Pointer(ifreq)))
runtime.KeepAlive(ifreq)
return err
}
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL
func Uname(uname *Utsname) error {

View File

@ -6,11 +6,7 @@
package unix
import (
"syscall"
)
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
import "syscall"
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
@ -49,5 +45,6 @@ func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64

View File

@ -6,11 +6,7 @@
package unix
import (
"syscall"
)
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
import "syscall"
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
@ -49,5 +45,6 @@ func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64

View File

@ -4,11 +4,9 @@
package unix
import (
"syscall"
)
import "syscall"
func ptrace(request int, pid int, addr uintptr, data uintptr) error {
func ptrace1(request int, pid int, addr uintptr, data uintptr) error {
return ENOTSUP
}

View File

@ -6,13 +6,7 @@
package unix
import (
"syscall"
)
func ptrace(request int, pid int, addr uintptr, data uintptr) error {
return ENOTSUP
}
import "syscall"
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
@ -51,5 +45,6 @@ func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sys Fstatfs(fd int, stat *Statfs_t) (err error)
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT
//sys Lstat(path string, stat *Stat_t) (err error)
//sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace
//sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, stat *Statfs_t) (err error)

View File

@ -47,6 +47,10 @@ type SockaddrDatalink struct {
raw RawSockaddrDatalink
}
func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
return nil, EAFNOSUPPORT
}
// Translate "kern.hostname" to []_C_int{0,1,2,3}.
func nametomib(name string) (mib []_C_int, err error) {
const siz = unsafe.Sizeof(mib[0])
@ -101,6 +105,19 @@ func Pipe(p []int) (err error) {
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) error {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err := pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return err
}
//sys extpread(fd int, p []byte, flags int, offset int64) (n int, err error)
func Pread(fd int, p []byte, offset int64) (n int, err error) {
return extpread(fd, p, 0, offset)

View File

@ -54,6 +54,10 @@ type SockaddrDatalink struct {
raw RawSockaddrDatalink
}
func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
return nil, EAFNOSUPPORT
}
// Translate "kern.hostname" to []_C_int{0,1,2,3}.
func nametomib(name string) (mib []_C_int, err error) {
const siz = unsafe.Sizeof(mib[0])

View File

@ -75,16 +75,3 @@ func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
}
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) error {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err := pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return err
}

View File

@ -106,15 +106,24 @@ func IoctlGetRTCTime(fd int) (*RTCTime, error) {
return &value, err
}
// IoctlGetWatchdogInfo fetches information about a watchdog device from the
// Linux watchdog API. For more information, see:
// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) {
var value WatchdogInfo
err := ioctl(fd, WDIOC_GETSUPPORT, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) {
var value RTCWkAlrm
err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value)))
return &value, err
}
// IoctlFileClone performs an FICLONERANGE ioctl operation to clone the range of
// data conveyed in value to the file associated with the file descriptor
// destFd. See the ioctl_ficlonerange(2) man page for details.
// IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the
// range of data conveyed in value to the file associated with the file
// descriptor destFd. See the ioctl_ficlonerange(2) man page for details.
func IoctlFileCloneRange(destFd int, value *FileCloneRange) error {
err := ioctl(destFd, FICLONERANGE, uintptr(unsafe.Pointer(value)))
runtime.KeepAlive(value)
@ -128,15 +137,22 @@ func IoctlFileClone(destFd, srcFd int) error {
return ioctl(destFd, FICLONE, uintptr(srcFd))
}
// IoctlFileClone performs an FIDEDUPERANGE ioctl operation to share the range of
// data conveyed in value with the file associated with the file descriptor
// destFd. See the ioctl_fideduperange(2) man page for details.
// IoctlFileDedupeRange performs an FIDEDUPERANGE ioctl operation to share the
// range of data conveyed in value with the file associated with the file
// descriptor destFd. See the ioctl_fideduperange(2) man page for details.
func IoctlFileDedupeRange(destFd int, value *FileDedupeRange) error {
err := ioctl(destFd, FIDEDUPERANGE, uintptr(unsafe.Pointer(value)))
runtime.KeepAlive(value)
return err
}
// IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For
// more information, see:
// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
func IoctlWatchdogKeepalive(fd int) error {
return ioctl(fd, WDIOC_KEEPALIVE, 0)
}
//sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
func Link(oldpath string, newpath string) (err error) {
@ -625,6 +641,36 @@ func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
}
// SockaddrCANJ1939 implements the Sockaddr interface for AF_CAN using J1939
// protocol (https://en.wikipedia.org/wiki/SAE_J1939). For more information
// on the purposes of the fields, check the official linux kernel documentation
// available here: https://www.kernel.org/doc/Documentation/networking/j1939.rst
type SockaddrCANJ1939 struct {
Ifindex int
Name uint64
PGN uint32
Addr uint8
raw RawSockaddrCAN
}
func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) {
if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
return nil, 0, EINVAL
}
sa.raw.Family = AF_CAN
sa.raw.Ifindex = int32(sa.Ifindex)
n := (*[8]byte)(unsafe.Pointer(&sa.Name))
for i := 0; i < 8; i++ {
sa.raw.Addr[i] = n[i]
}
p := (*[4]byte)(unsafe.Pointer(&sa.PGN))
for i := 0; i < 4; i++ {
sa.raw.Addr[i+8] = p[i]
}
sa.raw.Addr[12] = sa.Addr
return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
}
// SockaddrALG implements the Sockaddr interface for AF_ALG type sockets.
// SockaddrALG enables userspace access to the Linux kernel's cryptography
// subsystem. The Type and Name fields specify which type of hash or cipher
@ -936,6 +982,10 @@ func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil
}
var socketProtocol = func(fd int) (int, error) {
return GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
}
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family {
case AF_NETLINK:
@ -986,7 +1036,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
return sa, nil
case AF_INET:
proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
proto, err := socketProtocol(fd)
if err != nil {
return nil, err
}
@ -1012,7 +1062,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
}
case AF_INET6:
proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
proto, err := socketProtocol(fd)
if err != nil {
return nil, err
}
@ -1047,7 +1097,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
}
return sa, nil
case AF_BLUETOOTH:
proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
proto, err := socketProtocol(fd)
if err != nil {
return nil, err
}
@ -1134,20 +1184,43 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
return sa, nil
case AF_CAN:
pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa))
sa := &SockaddrCAN{
Ifindex: int(pp.Ifindex),
proto, err := socketProtocol(fd)
if err != nil {
return nil, err
}
rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
for i := 0; i < 4; i++ {
rx[i] = pp.Addr[i]
}
tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
for i := 0; i < 4; i++ {
tx[i] = pp.Addr[i+4]
}
return sa, nil
pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa))
switch proto {
case CAN_J1939:
sa := &SockaddrCANJ1939{
Ifindex: int(pp.Ifindex),
}
name := (*[8]byte)(unsafe.Pointer(&sa.Name))
for i := 0; i < 8; i++ {
name[i] = pp.Addr[i]
}
pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN))
for i := 0; i < 4; i++ {
pgn[i] = pp.Addr[i+8]
}
addr := (*[1]byte)(unsafe.Pointer(&sa.Addr))
addr[0] = pp.Addr[12]
return sa, nil
default:
sa := &SockaddrCAN{
Ifindex: int(pp.Ifindex),
}
rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
for i := 0; i < 4; i++ {
rx[i] = pp.Addr[i]
}
tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
for i := 0; i < 4; i++ {
tx[i] = pp.Addr[i+4]
}
return sa, nil
}
}
return nil, EAFNOSUPPORT
}

View File

@ -2,9 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
// so that go vet can check that they are correct.
// +build 386,linux
package unix

View File

@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// +build amd64,linux
// +build !gccgo
// +build gc
package unix

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,!gccgo
// +build linux,gc
package unix

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,!gccgo,386
// +build linux,gc,386
package unix

Some files were not shown because too many files have changed in this diff Show More