update-gopsutil (#10790)

This commit is contained in:
Huan Wang
2021-06-21 08:19:39 -06:00
committed by GitHub
parent d61bf59105
commit df74bc0cbb
21 changed files with 843 additions and 98 deletions

3
go.mod
View File

@@ -118,12 +118,11 @@ require (
github.com/ryanuber/go-glob v1.0.0
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529
github.com/seccomp/libseccomp-golang v0.9.2-0.20200314001724-bdab42bd5128 // indirect
github.com/shirou/gopsutil/v3 v3.21.2
github.com/shirou/gopsutil/v3 v3.21.6-0.20210619153009-7ea8062810b6
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c
github.com/stretchr/objx v0.2.0 // indirect
github.com/stretchr/testify v1.6.1
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/zclconf/go-cty v1.8.0
github.com/zclconf/go-cty-yaml v1.0.2
go.opencensus.io v0.22.1-0.20190713072201-b4a14686f0a9 // indirect

11
go.sum
View File

@@ -682,8 +682,8 @@ github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil v0.0.0-20181107111621-48177ef5f880 h1:1Ge4j/3uB2rxzPWD3TC+daeCw+w91z8UCUL/7WH5gn8=
github.com/shirou/gopsutil v0.0.0-20181107111621-48177ef5f880/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v3 v3.21.2 h1:fIOk3hyqV1oGKogfGNjUZa0lUbtlkx3+ZT0IoJth2uM=
github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
github.com/shirou/gopsutil/v3 v3.21.6-0.20210619153009-7ea8062810b6 h1:zvkkHVCTLzUWJD5D2Mfah194jXIyW9kKSm5PQJjXv+c=
github.com/shirou/gopsutil/v3 v3.21.6-0.20210619153009-7ea8062810b6/go.mod h1:JfVbDpIBLVzT8oKbvMg9P3wEIMDDpVn+LwHTKj0ST88=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
@@ -724,10 +724,8 @@ github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible h1:8uRvJleFpqLs
github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
github.com/tj/go-spin v1.1.0 h1:lhdWZsvImxvZ3q1C5OIB7d72DuOwP4O2NdBg9PyzNds=
github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4=
github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek=
github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4=
github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8=
github.com/tklauser/go-sysconf v0.3.6 h1:oc1sJWvKkmvIxhDHeKWvZS4f6AW+YcoguSfRF2/Hmo4=
github.com/tklauser/go-sysconf v0.3.6/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA=
github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8=
@@ -894,7 +892,6 @@ golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa h1:ZYxPR6aca/uhfRJyaOAtflSHjJYiktO7QnJC5ut7iY4=
golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=

View File

@@ -10,6 +10,7 @@ package cpu
#include <mach/mach_init.h>
#include <mach/mach_host.h>
#include <mach/host_info.h>
#include <TargetConditionals.h>
#if TARGET_OS_MAC
#include <libproc.h>
#endif

View File

@@ -141,9 +141,44 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
c.CPU = int32(t)
case "vendorId", "vendor_id":
c.VendorID = value
case "CPU implementer":
if v, err := strconv.ParseUint(value, 0, 8); err == nil {
switch v {
case 0x41:
c.VendorID = "ARM"
case 0x42:
c.VendorID = "Broadcom"
case 0x43:
c.VendorID = "Cavium"
case 0x44:
c.VendorID = "DEC"
case 0x46:
c.VendorID = "Fujitsu"
case 0x48:
c.VendorID = "HiSilicon"
case 0x49:
c.VendorID = "Infineon"
case 0x4d:
c.VendorID = "Motorola/Freescale"
case 0x4e:
c.VendorID = "NVIDIA"
case 0x50:
c.VendorID = "APM"
case 0x51:
c.VendorID = "Qualcomm"
case 0x56:
c.VendorID = "Marvell"
case 0x61:
c.VendorID = "Apple"
case 0x69:
c.VendorID = "Intel"
case 0xc0:
c.VendorID = "Ampere"
}
}
case "cpu family":
c.Family = value
case "model":
case "model", "CPU part":
c.Model = value
case "model name", "cpu":
c.ModelName = value
@@ -153,7 +188,7 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
c.Family = "POWER"
c.VendorID = "IBM"
}
case "stepping", "revision":
case "stepping", "revision", "CPU revision":
val := value
if key == "revision" {
@@ -287,7 +322,10 @@ func CountsWithContext(ctx context.Context, logical bool) (int, error) {
for _, line := range lines {
line = strings.ToLower(line)
if strings.HasPrefix(line, "processor") {
ret++
_, err = strconv.Atoi(strings.TrimSpace(line[strings.IndexByte(line, ':')+1:]))
if err == nil {
ret++
}
}
}
}

View File

@@ -179,7 +179,7 @@ func parseISAInfo(cmdOutput string) ([]string, error) {
return flags, nil
}
var psrInfoMatch = regexp.MustCompile(`The physical processor has (?:([\d]+) virtual processor \(([\d]+)\)|([\d]+) cores and ([\d]+) virtual processors[^\n]+)\n(?:\s+ The core has.+\n)*\s+.+ \((\w+) ([\S]+) family (.+) model (.+) step (.+) clock (.+) MHz\)\n[\s]*(.*)`)
var psrInfoMatch = regexp.MustCompile(`The physical processor has (?:([\d]+) virtual processors? \(([\d-]+)\)|([\d]+) cores and ([\d]+) virtual processors[^\n]+)\n(?:\s+ The core has.+\n)*\s+.+ \((\w+) ([\S]+) family (.+) model (.+) step (.+) clock (.+) MHz\)\n[\s]*(.*)`)
const (
psrNumCoresOffset = 1

View File

@@ -18,7 +18,6 @@ var (
)
type win32_Processor struct {
LoadPercentage *uint16
Family uint16
Manufacturer string
Name string

View File

@@ -0,0 +1,37 @@
// +build openbsd
// +build arm64
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs disk/types_openbsd.go
package disk
const (
devstat_NO_DATA = 0x00
devstat_READ = 0x01
devstat_WRITE = 0x02
devstat_FREE = 0x03
)
const (
sizeOfDiskstats = 0x70
)
type Diskstats struct {
Name [16]int8
Busy int32
Rxfer uint64
Wxfer uint64
Seek uint64
Rbytes uint64
Wbytes uint64
Attachtime Timeval
Timestamp Timeval
Time Timeval
}
type Timeval struct {
Sec int64
Usec int64
}
type Diskstat struct{}
type bintime struct{}

View File

@@ -285,7 +285,7 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil
family = "fedora"
case "oracle", "centos", "redhat", "scientific", "enterpriseenterprise", "amazon", "xenserver", "cloudlinux", "ibm_powerkvm":
family = "rhel"
case "suse", "opensuse", "sles":
case "suse", "opensuse", "opensuse-leap", "opensuse-tumbleweed", "opensuse-tumbleweed-kubic", "sles", "sled", "caasp":
family = "suse"
case "gentoo":
family = "gentoo"

View File

@@ -78,7 +78,7 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) {
var u Utmp
br := bytes.NewReader(b)
err := binary.Read(br, binary.LittleEndian, &u)
if err != nil || u.Time == 0 {
if err != nil || u.Time == 0 || u.Name[0] == 0 {
continue
}
user := UserStat{

View File

@@ -0,0 +1,33 @@
// +build openbsd
// +build arm64
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs host/types_openbsd.go
package host
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
sizeOfUtmp = 0x130
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type Utmp struct {
Line [8]int8
Name [32]int8
Host [256]int8
Time int64
}
type Timeval struct {
Sec int64
Usec int64
}

View File

@@ -352,6 +352,16 @@ func HostDev(combineWith ...string) string {
return GetEnv("HOST_DEV", "/dev", combineWith...)
}
// MockEnv set environment variable and return revert function.
// MockEnv should be used testing only.
func MockEnv(key string, value string) func() {
original := os.Getenv(key)
os.Setenv(key, value)
return func() {
os.Setenv(key, original)
}
}
// getSysctrlEnv sets LC_ALL=C in a list of env vars for use when running
// sysctl commands (see DoSysctrl).
func getSysctrlEnv(env []string) []string {

View File

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

View File

@@ -14,6 +14,7 @@ import (
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/shirou/gopsutil/v3/net"
"github.com/tklauser/go-sysconf"
"golang.org/x/sys/unix"
)
@@ -27,9 +28,15 @@ const (
KernProcPathname = 12 // path to executable
)
const (
clockTicks = 100 // C.sysconf(C._SC_CLK_TCK)
)
var clockTicks = 100 // default value
func init() {
clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK)
// ignore errors
if err == nil {
clockTicks = int(clkTck)
}
}
type _Ctype_struct___0 struct {
Pad uint64
@@ -38,7 +45,7 @@ type _Ctype_struct___0 struct {
func pidsWithContext(ctx context.Context) ([]int32, error) {
var ret []int32
pids, err := callPsWithContext(ctx, "pid", 0, false)
pids, err := callPsWithContext(ctx, "pid", 0, false, false)
if err != nil {
return ret, err
}
@@ -55,7 +62,7 @@ func pidsWithContext(ctx context.Context) ([]int32, error) {
}
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
r, err := callPsWithContext(ctx, "ppid", p.Pid, false)
r, err := callPsWithContext(ctx, "ppid", p.Pid, false, false)
if err != nil {
return 0, err
}
@@ -76,16 +83,16 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
name := common.IntToString(k.Proc.P_comm[:])
if len(name) >= 15 {
cmdlineSlice, err := p.CmdlineSliceWithContext(ctx)
cmdName, err := p.cmdNameWithContext(ctx)
if err != nil {
return "", err
}
if len(cmdlineSlice) > 0 {
extendedName := filepath.Base(cmdlineSlice[0])
if len(cmdName) > 0 {
extendedName := filepath.Base(cmdName[0])
if strings.HasPrefix(extendedName, p.name) {
name = extendedName
} else {
name = cmdlineSlice[0]
name = cmdName[0]
}
}
}
@@ -94,20 +101,29 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
r, err := callPsWithContext(ctx, "command", p.Pid, false)
r, err := callPsWithContext(ctx, "command", p.Pid, false, false)
if err != nil {
return "", err
}
return strings.Join(r[0], " "), err
}
// cmdNameWithContext returns the command name (including spaces) without any arguments
func (p *Process) cmdNameWithContext(ctx context.Context) ([]string, error) {
r, err := callPsWithContext(ctx, "command", p.Pid, false, true)
if err != nil {
return nil, err
}
return r[0], err
}
// 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) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
r, err := callPsWithContext(ctx, "command", p.Pid, false)
r, err := callPsWithContext(ctx, "command", p.Pid, false, false)
if err != nil {
return nil, err
}
@@ -115,7 +131,7 @@ func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error)
}
func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
r, err := callPsWithContext(ctx, "etime", p.Pid, false)
r, err := callPsWithContext(ctx, "etime", p.Pid, false, false)
if err != nil {
return 0, err
}
@@ -163,7 +179,7 @@ func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
}
func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) {
r, err := callPsWithContext(ctx, "state", p.Pid, false)
r, err := callPsWithContext(ctx, "state", p.Pid, false, false)
if err != nil {
return []string{""}, err
}
@@ -255,7 +271,7 @@ func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, e
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
r, err := callPsWithContext(ctx, "utime,stime", p.Pid, true)
r, err := callPsWithContext(ctx, "utime,stime", p.Pid, true, false)
if err != nil {
return 0, err
}
@@ -305,11 +321,11 @@ func convertCPUTimes(s string) (ret float64, err error) {
t += h * clockTicks
h, err = strconv.Atoi(_t[1])
t += h
return float64(t) / clockTicks, nil
return float64(t) / float64(clockTicks), nil
}
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
r, err := callPsWithContext(ctx, "utime,stime", p.Pid, false)
r, err := callPsWithContext(ctx, "utime,stime", p.Pid, false, false)
if err != nil {
return nil, err
@@ -333,7 +349,7 @@ func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error)
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
r, err := callPsWithContext(ctx, "rss,vsize,pagein", p.Pid, false)
r, err := callPsWithContext(ctx, "rss,vsize,pagein", p.Pid, false, false)
if err != nil {
return nil, err
}
@@ -421,7 +437,7 @@ func (p *Process) getKProc() (*KinfoProc, error) {
// Return value deletes Header line(you must not input wrong arg).
// And splited by Space. Caller have responsibility to manage.
// If passed arg pid is 0, get information from all process.
func callPsWithContext(ctx context.Context, arg string, pid int32, threadOption bool) ([][]string, error) {
func callPsWithContext(ctx context.Context, arg string, pid int32, threadOption bool, nameOption bool) ([][]string, error) {
bin, err := exec.LookPath("ps")
if err != nil {
return [][]string{}, err
@@ -435,6 +451,9 @@ func callPsWithContext(ctx context.Context, arg string, pid int32, threadOption
} else {
cmd = []string{"-x", "-o", arg, "-p", strconv.Itoa(int(pid))}
}
if nameOption {
cmd = append(cmd, "-c")
}
out, err := invoke.CommandWithContext(ctx, bin, cmd...)
if err != nil {
return [][]string{}, err
@@ -444,11 +463,15 @@ func callPsWithContext(ctx context.Context, arg string, pid int32, threadOption
var ret [][]string
for _, l := range lines[1:] {
var lr []string
for _, r := range strings.Split(l, " ") {
if r == "" {
continue
if nameOption {
lr = append(lr, l)
} else {
for _, r := range strings.Split(l, " ") {
if r == "" {
continue
}
lr = append(lr, strings.TrimSpace(r))
}
lr = append(lr, strings.TrimSpace(r))
}
if len(lr) != 0 {
ret = append(ret, lr)

View File

@@ -120,22 +120,25 @@ type Sigacts struct{}
type ExternProc struct {
P_un [16]byte
P_vmspace *Vmspace
P_sigacts *Sigacts
P_vmspace uint64
P_sigacts uint64
Pad_cgo_0 [3]byte
P_flag int32
P_stat int8
P_pid int32
P_oppid int32
P_dupfd int32
User_stack *int8
Exit_thread *byte
Pad_cgo_1 [4]byte
User_stack uint64
Exit_thread uint64
P_debugger int32
Sigwait int32
P_estcpu uint32
P_cpticks int32
P_pctcpu uint32
P_wchan *byte
P_wmesg *int8
Pad_cgo_2 [4]byte
P_wchan uint64
P_wmesg uint64
P_swtime uint32
P_slptime uint32
P_realtimer Itimerval
@@ -144,9 +147,11 @@ type ExternProc struct {
P_sticks uint64
P_iticks uint64
P_traceflag int32
P_tracep *Vnode
Pad_cgo_3 [4]byte
P_tracep uint64
P_siglist int32
P_textvp *Vnode
Pad_cgo_4 [4]byte
P_textvp uint64
P_holdcnt int32
P_sigmask uint32
P_sigignore uint32
@@ -155,11 +160,13 @@ type ExternProc struct {
P_usrpri uint8
P_nice int8
P_comm [17]int8
P_pgrp *Pgrp
P_addr *UserStruct
Pad_cgo_5 [4]byte
P_pgrp uint64
P_addr uint64
P_xstat uint16
P_acflag uint16
P_ru *Rusage
Pad_cgo_6 [4]byte
P_ru uint64
}
type Itimerval struct {

View File

@@ -1,4 +1,4 @@
// +build !darwin,!linux,!freebsd,!openbsd,!windows
// +build !darwin,!linux,!freebsd,!openbsd,!windows,!solaris
package process

View File

@@ -18,15 +18,23 @@ import (
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/shirou/gopsutil/v3/net"
"github.com/tklauser/go-sysconf"
"golang.org/x/sys/unix"
)
var pageSize = uint64(os.Getpagesize())
const (
prioProcess = 0 // linux/resource.h
clockTicks = 100 // C.sysconf(C._SC_CLK_TCK)
)
const prioProcess = 0 // linux/resource.h
var clockTicks = 100 // default value
func init() {
clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK)
// ignore errors
if err == nil {
clockTicks = int(clkTck)
}
}
// MemoryInfoExStat is different between OSes
type MemoryInfoExStat struct {
@@ -485,11 +493,11 @@ func limitToUint(val string) (uint64, error) {
if val == "unlimited" {
return math.MaxUint64, nil
} else {
res, err := strconv.ParseInt(val, 10, 32)
res, err := strconv.ParseUint(val, 10, 64)
if err != nil {
return 0, err
}
return uint64(res), nil
return res, nil
}
}
@@ -930,30 +938,45 @@ func (p *Process) fillFromStatusWithContext(ctx context.Context) error {
}
p.memInfo.Locked = v * 1024
case "SigPnd":
if len(value) > 16 {
value = value[len(value)-16:]
}
v, err := strconv.ParseUint(value, 16, 64)
if err != nil {
return err
}
p.sigInfo.PendingThread = v
case "ShdPnd":
if len(value) > 16 {
value = value[len(value)-16:]
}
v, err := strconv.ParseUint(value, 16, 64)
if err != nil {
return err
}
p.sigInfo.PendingProcess = v
case "SigBlk":
if len(value) > 16 {
value = value[len(value)-16:]
}
v, err := strconv.ParseUint(value, 16, 64)
if err != nil {
return err
}
p.sigInfo.Blocked = v
case "SigIgn":
if len(value) > 16 {
value = value[len(value)-16:]
}
v, err := strconv.ParseUint(value, 16, 64)
if err != nil {
return err
}
p.sigInfo.Ignored = v
case "SigCgt":
if len(value) > 16 {
value = value[len(value)-16:]
}
v, err := strconv.ParseUint(value, 16, 64)
if err != nil {
return err
@@ -979,28 +1002,24 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui
if err != nil {
return 0, 0, nil, 0, 0, 0, nil, err
}
fields := strings.Fields(string(contents))
// Indexing from one, as described in `man proc` about the file /proc/[pid]/stat
fields := splitProcStat(contents)
i := 1
for !strings.HasSuffix(fields[i], ")") {
i++
}
terminal, err := strconv.ParseUint(fields[i+5], 10, 64)
terminal, err := strconv.ParseUint(fields[7], 10, 64)
if err != nil {
return 0, 0, nil, 0, 0, 0, nil, err
}
ppid, err := strconv.ParseInt(fields[i+2], 10, 32)
ppid, err := strconv.ParseInt(fields[4], 10, 32)
if err != nil {
return 0, 0, nil, 0, 0, 0, nil, err
}
utime, err := strconv.ParseFloat(fields[i+12], 64)
utime, err := strconv.ParseFloat(fields[14], 64)
if err != nil {
return 0, 0, nil, 0, 0, 0, nil, err
}
stime, err := strconv.ParseFloat(fields[i+13], 64)
stime, err := strconv.ParseFloat(fields[15], 64)
if err != nil {
return 0, 0, nil, 0, 0, 0, nil, err
}
@@ -1008,27 +1027,32 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui
// There is no such thing as iotime in stat file. As an approximation, we
// will use delayacct_blkio_ticks (aggregated block I/O delays, as per Linux
// 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
var iotime float64
if len(fields) > 42 {
iotime, err = strconv.ParseFloat(fields[42], 64)
if err != nil {
iotime = 0 // Ancient linux version, most likely
}
} else {
iotime = 0 // e.g. SmartOS containers
}
cpuTimes := &cpu.TimesStat{
CPU: "cpu",
User: float64(utime / clockTicks),
System: float64(stime / clockTicks),
Iowait: float64(iotime / clockTicks),
User: utime / float64(clockTicks),
System: stime / float64(clockTicks),
Iowait: iotime / float64(clockTicks),
}
bootTime, _ := common.BootTimeWithContext(ctx)
t, err := strconv.ParseUint(fields[i+20], 10, 64)
t, err := strconv.ParseUint(fields[22], 10, 64)
if err != nil {
return 0, 0, nil, 0, 0, 0, nil, err
}
ctime := (t / uint64(clockTicks)) + uint64(bootTime)
createTime := int64(ctime * 1000)
rtpriority, err := strconv.ParseInt(fields[i+16], 10, 32)
rtpriority, err := strconv.ParseInt(fields[18], 10, 32)
if err != nil {
return 0, 0, nil, 0, 0, 0, nil, err
}
@@ -1043,19 +1067,19 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui
snice, _ := unix.Getpriority(prioProcess, int(pid))
nice := int32(snice) // FIXME: is this true?
minFault, err := strconv.ParseUint(fields[i+8], 10, 64)
minFault, err := strconv.ParseUint(fields[10], 10, 64)
if err != nil {
return 0, 0, nil, 0, 0, 0, nil, err
}
cMinFault, err := strconv.ParseUint(fields[i+9], 10, 64)
cMinFault, err := strconv.ParseUint(fields[11], 10, 64)
if err != nil {
return 0, 0, nil, 0, 0, 0, nil, err
}
majFault, err := strconv.ParseUint(fields[i+10], 10, 64)
majFault, err := strconv.ParseUint(fields[12], 10, 64)
if err != nil {
return 0, 0, nil, 0, 0, 0, nil, err
}
cMajFault, err := strconv.ParseUint(fields[i+11], 10, 64)
cMajFault, err := strconv.ParseUint(fields[13], 10, 64)
if err != nil {
return 0, 0, nil, 0, 0, 0, nil, err
}
@@ -1121,3 +1145,16 @@ func readPidsFromDir(path string) ([]int32, error) {
return ret, nil
}
func splitProcStat(content []byte) []string {
nameStart := bytes.IndexByte(content, '(')
nameEnd := bytes.LastIndexByte(content, ')')
restFields := strings.Fields(string(content[nameEnd+2:])) // +2 skip ') '
name := content[nameStart+1 : nameEnd]
pid := strings.TrimSpace(string(content[:nameStart]))
fields := make([]string, 3, len(restFields)+3)
fields[1] = string(pid)
fields[2] = string(name)
fields = append(fields, restFields...)
return fields
}

View File

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

View File

@@ -1,4 +1,4 @@
// +build linux freebsd openbsd darwin
// +build linux freebsd openbsd darwin solaris
package process
@@ -71,6 +71,30 @@ func getTerminalMap() (map[uint64]string, error) {
return ret, nil
}
// isMount is a port of python's os.path.ismount()
// https://github.com/python/cpython/blob/08ff4369afca84587b1c82034af4e9f64caddbf2/Lib/posixpath.py#L186-L216
// https://docs.python.org/3/library/os.path.html#os.path.ismount
func isMount(path string) bool {
// Check symlinkness with os.Lstat; unix.DT_LNK is not portable
fileInfo, err := os.Lstat(path)
if err != nil {
return false
}
if fileInfo.Mode() & os.ModeSymlink != 0 {
return false
}
var stat1 unix.Stat_t
if err := unix.Lstat(path, &stat1); err != nil {
return false
}
parent := filepath.Join(path, "..")
var stat2 unix.Stat_t
if err := unix.Lstat(parent, &stat2); err != nil {
return false
}
return stat1.Dev != stat2.Dev || stat1.Ino == stat2.Ino
}
func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
if pid <= 0 {
return false, fmt.Errorf("invalid pid %v", pid)
@@ -80,10 +104,7 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
return false, err
}
if _, err := os.Stat(common.HostProc()); err == nil { //Means that proc filesystem exist
// Checking PID existence based on existence of /<HOST_PROC>/proc/<PID> folder
// This covers the case when running inside container with a different process namespace (by default)
if isMount(common.HostProc()) { // if /<HOST_PROC>/proc exists and is mounted, check if /<HOST_PROC>/proc/<PID> folder exists
_, err := os.Stat(common.HostProc(strconv.Itoa(int(pid))))
if os.IsNotExist(err) {
return false, nil
@@ -91,8 +112,7 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
return err == nil, err
}
//'/proc' filesystem is not exist, checking of PID existence is done via signalling the process
//Make sense only if we run in the same process namespace
// procfs does not exist or is not mounted, check PID existence by signalling the pid
err = proc.Signal(syscall.Signal(0))
if err == nil {
return true, nil
@@ -158,4 +178,3 @@ func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
}
return "", nil
}

View File

@@ -0,0 +1,305 @@
package process
import (
"bytes"
"context"
"io/ioutil"
"os"
"strconv"
"strings"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/shirou/gopsutil/v3/net"
)
type MemoryMapsStat struct {
Path string `json:"path"`
Rss uint64 `json:"rss"`
Size uint64 `json:"size"`
Pss uint64 `json:"pss"`
SharedClean uint64 `json:"sharedClean"`
SharedDirty uint64 `json:"sharedDirty"`
PrivateClean uint64 `json:"privateClean"`
PrivateDirty uint64 `json:"privateDirty"`
Referenced uint64 `json:"referenced"`
Anonymous uint64 `json:"anonymous"`
Swap uint64 `json:"swap"`
}
type MemoryInfoExStat struct {
}
func pidsWithContext(ctx context.Context) ([]int32, error) {
return readPidsFromDir(common.HostProc())
}
func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
out := []*Process{}
pids, err := PidsWithContext(ctx)
if err != nil {
return out, err
}
for _, pid := range pids {
p, err := NewProcessWithContext(ctx, pid)
if err != nil {
continue
}
out = append(out, p)
}
return out, nil
}
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) TgidWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
exe, err := p.fillFromPathAOutWithContext(ctx)
if os.IsNotExist(err) {
exe, err = p.fillFromExecnameWithContext(ctx)
}
return exe, err
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
return p.fillFromCmdlineWithContext(ctx)
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
return p.fillSliceFromCmdlineWithContext(ctx)
}
func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return p.fillFromPathCwdWithContext(ctx)
}
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) {
return []string{""}, common.ErrNotImplementedError
}
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
return false, common.ErrNotImplementedError
}
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
return 0, 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) IOCountersWithContext(ctx context.Context) (*IOCountersStat, 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) {
_, fnames, err := p.fillFromfdListWithContext(ctx)
return int32(len(fnames)), err
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, 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) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
return nil, common.ErrNotImplementedError
}
/**
** Internal functions
**/
func (p *Process) fillFromfdListWithContext(ctx context.Context) (string, []string, error) {
pid := p.Pid
statPath := common.HostProc(strconv.Itoa(int(pid)), "fd")
d, err := os.Open(statPath)
if err != nil {
return statPath, []string{}, err
}
defer d.Close()
fnames, err := d.Readdirnames(-1)
return statPath, fnames, err
}
func (p *Process) fillFromPathCwdWithContext(ctx context.Context) (string, error) {
pid := p.Pid
cwdPath := common.HostProc(strconv.Itoa(int(pid)), "path", "cwd")
cwd, err := os.Readlink(cwdPath)
if err != nil {
return "", err
}
return cwd, nil
}
func (p *Process) fillFromPathAOutWithContext(ctx context.Context) (string, error) {
pid := p.Pid
cwdPath := common.HostProc(strconv.Itoa(int(pid)), "path", "a.out")
exe, err := os.Readlink(cwdPath)
if err != nil {
return "", err
}
return exe, nil
}
func (p *Process) fillFromExecnameWithContext(ctx context.Context) (string, error) {
pid := p.Pid
execNamePath := common.HostProc(strconv.Itoa(int(pid)), "execname")
exe, err := ioutil.ReadFile(execNamePath)
if err != nil {
return "", err
}
return string(exe), nil
}
func (p *Process) fillFromCmdlineWithContext(ctx context.Context) (string, error) {
pid := p.Pid
cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline")
cmdline, err := ioutil.ReadFile(cmdPath)
if err != nil {
return "", err
}
ret := strings.FieldsFunc(string(cmdline), func(r rune) bool {
if r == '\u0000' {
return true
}
return false
})
return strings.Join(ret, " "), nil
}
func (p *Process) fillSliceFromCmdlineWithContext(ctx context.Context) ([]string, error) {
pid := p.Pid
cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline")
cmdline, err := ioutil.ReadFile(cmdPath)
if err != nil {
return nil, err
}
if len(cmdline) == 0 {
return nil, nil
}
if cmdline[len(cmdline)-1] == 0 {
cmdline = cmdline[:len(cmdline)-1]
}
parts := bytes.Split(cmdline, []byte{0})
var strParts []string
for _, p := range parts {
strParts = append(strParts, string(p))
}
return strParts, nil
}
func readPidsFromDir(path string) ([]int32, error) {
var ret []int32
d, err := os.Open(path)
if err != nil {
return nil, err
}
defer d.Close()
fnames, err := d.Readdirnames(-1)
if err != nil {
return nil, err
}
for _, fname := range fnames {
pid, err := strconv.ParseInt(fname, 10, 32)
if err != nil {
// if not numeric name, just skip
continue
}
ret = append(ret, int32(pid))
}
return ret, nil
}

View File

@@ -38,6 +38,8 @@ var (
processorArchitecture uint
)
const processQueryInformation = windows.PROCESS_QUERY_LIMITED_INFORMATION | windows.PROCESS_QUERY_INFORMATION // WinXP doesn't know PROCESS_QUERY_LIMITED_INFORMATION
type systemProcessorInformation struct {
ProcessorArchitecture uint16
ProcessorLevel uint16
@@ -204,7 +206,7 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
return false, err
}
const STILL_ACTIVE = 259 // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getexitcodeprocess
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
h, err := windows.OpenProcess(processQueryInformation, false, uint32(pid))
if err == windows.ERROR_ACCESS_DENIED {
return true, nil
}
@@ -258,7 +260,7 @@ func (p *Process) TgidWithContext(ctx context.Context) (int32, error) {
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(p.Pid))
c, err := windows.OpenProcess(processQueryInformation, false, uint32(p.Pid))
if err != nil {
return "", err
}
@@ -332,7 +334,7 @@ func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
pid := p.Pid
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
c, err := windows.OpenProcess(processQueryInformation, false, uint32(pid))
if err != nil {
return "", err
}
@@ -382,7 +384,7 @@ var priorityClasses = map[int]int32{
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(p.Pid))
c, err := windows.OpenProcess(processQueryInformation, false, uint32(p.Pid))
if err != nil {
return 0, err
}
@@ -411,7 +413,7 @@ func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) (
}
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(p.Pid))
c, err := windows.OpenProcess(processQueryInformation, false, uint32(p.Pid))
if err != nil {
return nil, err
}
@@ -661,7 +663,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
func getRusage(pid int32) (*windows.Rusage, error) {
var CPU windows.Rusage
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
c, err := windows.OpenProcess(processQueryInformation, false, uint32(pid))
if err != nil {
return nil, err
}
@@ -676,7 +678,7 @@ func getRusage(pid int32) (*windows.Rusage, error) {
func getMemoryInfo(pid int32) (PROCESS_MEMORY_COUNTERS, error) {
var mem PROCESS_MEMORY_COUNTERS
c, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
c, err := windows.OpenProcess(processQueryInformation, false, uint32(pid))
if err != nil {
return mem, err
}
@@ -710,7 +712,7 @@ type SYSTEM_TIMES struct {
func getProcessCPUTimes(pid int32) (SYSTEM_TIMES, error) {
var times SYSTEM_TIMES
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
h, err := windows.OpenProcess(processQueryInformation, false, uint32(pid))
if err != nil {
return times, err
}
@@ -751,7 +753,7 @@ func is32BitProcess(procHandle syscall.Handle) bool {
}
func getProcessCommandLine(pid int32) (string, error) {
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION|windows.PROCESS_VM_READ, false, uint32(pid))
h, err := windows.OpenProcess(processQueryInformation|windows.PROCESS_VM_READ, false, uint32(pid))
if err == windows.ERROR_ACCESS_DENIED || err == windows.ERROR_INVALID_PARAMETER {
return "", nil
}

5
vendor/modules.txt vendored
View File

@@ -727,7 +727,7 @@ github.com/sean-/seed
# github.com/seccomp/libseccomp-golang v0.9.2-0.20200314001724-bdab42bd5128
## explicit
github.com/seccomp/libseccomp-golang
# github.com/shirou/gopsutil/v3 v3.21.2
# github.com/shirou/gopsutil/v3 v3.21.6-0.20210619153009-7ea8062810b6
## explicit
github.com/shirou/gopsutil/v3/cpu
github.com/shirou/gopsutil/v3/disk
@@ -767,8 +767,7 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312
# github.com/tj/go-spin v1.1.0
github.com/tj/go-spin
# github.com/tklauser/go-sysconf v0.3.5
## explicit
# github.com/tklauser/go-sysconf v0.3.6
github.com/tklauser/go-sysconf
# github.com/tklauser/numcpus v0.2.2
github.com/tklauser/numcpus