Merge branch 'master' into add-plan9-cpu

pull/1155/head
shirou 3 years ago committed by GitHub
commit 8f489b62d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,50 @@
on: [push, pull_request]
name: Build Test
jobs:
build_test_v2:
env:
GOPATH: ${{ github.workspace }}
GO111MODULE: off
strategy:
matrix:
go-version: [1.16.x, 1.17.x]
runs-on: ubuntu-20.04
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
with:
path: ${{ github.workspace }}/src/github.com/shirou/gopsutil
- name: Get dependencies
if: runner.os != 'Windows'
run: |
if ! command -v dep &>/dev/null; then
mkdir -p $GOPATH/bin
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
echo "PATH=$GOPATH/bin:$PATH" >> $GITHUB_PATH
fi
cd $GOPATH/src/github.com/shirou/gopsutil
dep ensure
# exclude v3 from being run with ./...
rm -rf $GOPATH/src/github.com/shirou/gopsutil/v3
- name: Build Test v2
run: |
cd $GOPATH/src/github.com/shirou/gopsutil && make build_test
build_test_v3:
strategy:
matrix:
go-version: [1.16.x, 1.17.x]
runs-on: ubuntu-20.04
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
- name: Build Test v3
run: |
cd v3 && make build_test

26
Gopkg.lock generated

@ -2,12 +2,12 @@
[[projects]]
digest = "1:9909e0a06cff3bd88841c9d2e0cc91b0a431676009018c74c3315f33b49b0046"
digest = "1:3a991e1f8ab48d1445b5106b628609285cecb1bfe5abdd078b4320d32ec0f3ee"
name = "github.com/StackExchange/wmi"
packages = ["."]
pruneopts = "UT"
revision = "cbe66965904dbe8a6cd589e2298e5d8b986bd7dd"
version = "1.1.0"
revision = "441642c1665945335b93778e496324884ce569e7"
version = "v1.2.1"
[[projects]]
digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec"
@ -18,15 +18,15 @@
version = "v1.1.1"
[[projects]]
digest = "1:440028f55cb322d8cb5b9d5ebec298a00b7d74690a658fe6b1c0c0b44341bfae"
digest = "1:fa413ac44630f9ca77bf7bb629804106a50cd5af351f89ed1e23e08e6173c5d0"
name = "github.com/go-ole/go-ole"
packages = [
".",
"oleutil",
]
pruneopts = "UT"
revision = "97b6244175ae18ea6eef668034fd6565847501c9"
version = "v1.2.4"
revision = "8b1f7f90f6b1728609c9694f2cff140d34fd91f8"
version = "v1.2.6"
[[projects]]
digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe"
@ -37,15 +37,15 @@
version = "v1.0.0"
[[projects]]
digest = "1:efd3a1c83607945eb57cb6cf9c5a87f1c709fb9fdfbd3d8f729ff03943275465"
digest = "1:5c7b4a9fefe5b7b160d2cf0ec8457de81db92038c45c88d7d59493568308cc5d"
name = "github.com/stretchr/testify"
packages = [
"assert",
"require",
]
pruneopts = "UT"
revision = "004e3cb72213e5e727e4e08f668ee6c8f27e5d32"
version = "v1.6.0"
revision = "acba37e5db06f0093b465a7d47822bf13644b66c"
version = "v1.7.0"
[[projects]]
digest = "1:dc2f804edbbcc4e7c5385791b8703da9b6bc6e22e698233f919c19da6286cf11"
@ -65,7 +65,7 @@
[[projects]]
branch = "master"
digest = "1:1672d2eb5799465379f6016fa509eadd72c69e3eb2bf3cdfea9222e64e163b94"
digest = "1:cded1795a2d143aa9940244639afeaeecc5cfb9bb2a01bdcaa4087e9beb989c0"
name = "golang.org/x/sys"
packages = [
"internal/unsafeheader",
@ -75,15 +75,15 @@
"windows/svc/mgr",
]
pruneopts = "UT"
revision = "134d130e1a049f4194ae9920ac9f96455cde360d"
revision = "69063c4bb744bc56492b1a0533d73a23406b0bc2"
[[projects]]
branch = "v3"
digest = "1:f87d6c8edf5e57ae4a355abc05aca1dbf38b073068bba96c1fbbff852a1e2fd3"
digest = "1:107a619d3c3bcca214b2b7db810a5dffcd74b5d0262813cb2986e063fae2722f"
name = "gopkg.in/yaml.v3"
packages = ["."]
pruneopts = "UT"
revision = "2ff61e1afc866138abf1a8adf3cc89721090ac31"
revision = "496545a6307b2a7d7a710fd516e5e16e8ab62dbc"
[solve-meta]
analyzer-name = "dep"

@ -4,7 +4,6 @@ package mem
import (
"context"
"errors"
"fmt"
"os/exec"
"regexp"
@ -68,7 +67,7 @@ func zoneName() (string, error) {
return strings.TrimSpace(string(out)), nil
}
var globalZoneMemoryCapacityMatch = regexp.MustCompile(`memory size: ([\d]+) Megabytes`)
var globalZoneMemoryCapacityMatch = regexp.MustCompile(`[Mm]emory size: (\d+) Megabytes`)
func globalZoneMemoryCapacity() (uint64, error) {
prtconf, err := exec.LookPath("prtconf")
@ -84,7 +83,7 @@ func globalZoneMemoryCapacity() (uint64, error) {
match := globalZoneMemoryCapacityMatch.FindAllStringSubmatch(string(out), -1)
if len(match) != 1 {
return 0, errors.New("memory size not contained in output of /usr/sbin/prtconf")
return 0, fmt.Errorf("memory size not contained in output of %q", prtconf)
}
totalMB, err := strconv.ParseUint(match[0][1], 10, 64)
@ -95,7 +94,7 @@ func globalZoneMemoryCapacity() (uint64, error) {
return totalMB * 1024 * 1024, nil
}
var kstatMatch = regexp.MustCompile(`([^\s]+)[\s]+([^\s]*)`)
var kstatMatch = regexp.MustCompile(`(\S+)\s+(\S*)`)
func nonGlobalZoneMemoryCapacity() (uint64, error) {
kstat, err := exec.LookPath("kstat")
@ -122,7 +121,7 @@ func nonGlobalZoneMemoryCapacity() (uint64, error) {
return memSizeBytes, nil
}
const swapsCommand = "swap"
const swapCommand = "swap"
// The blockSize as reported by `swap -l`. See https://docs.oracle.com/cd/E23824_01/html/821-1459/fsswap-52195.html
const blockSize = 512
@ -141,13 +140,13 @@ func SwapDevices() ([]*SwapDevice, error) {
}
func SwapDevicesWithContext(ctx context.Context) ([]*SwapDevice, error) {
swapsCommandPath, err := exec.LookPath(swapsCommand)
swapCommandPath, err := exec.LookPath(swapCommand)
if err != nil {
return nil, fmt.Errorf("could not find command %q: %w", swapCommand, err)
}
output, err := invoke.CommandWithContext(swapsCommandPath, "-l")
output, err := invoke.CommandWithContext(ctx, swapCommandPath, "-l")
if err != nil {
return nil, fmt.Errorf("could not execute %q: %w", swapsCommand, err)
return nil, fmt.Errorf("could not execute %q: %w", swapCommand, err)
}
return parseSwapsCommandOutput(string(output))
@ -156,22 +155,22 @@ func SwapDevicesWithContext(ctx context.Context) ([]*SwapDevice, error) {
func parseSwapsCommandOutput(output string) ([]*SwapDevice, error) {
lines := strings.Split(output, "\n")
if len(lines) == 0 {
return nil, fmt.Errorf("could not parse output of %q: no lines in %q", swapsCommand, output)
return nil, fmt.Errorf("could not parse output of %q: no lines in %q", swapCommand, output)
}
// Check header headerFields are as expected.
headerFields := strings.Fields(lines[0])
if len(headerFields) < freeBlocksCol {
return nil, fmt.Errorf("couldn't parse %q: too few fields in header %q", swapsCommand, lines[0])
return nil, fmt.Errorf("couldn't parse %q: too few fields in header %q", swapCommand, lines[0])
}
if headerFields[nameCol] != "swapfile" {
return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapsCommand, headerFields[nameCol], "swapfile")
return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapCommand, headerFields[nameCol], "swapfile")
}
if headerFields[totalBlocksCol] != "blocks" {
return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapsCommand, headerFields[totalBlocksCol], "blocks")
return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapCommand, headerFields[totalBlocksCol], "blocks")
}
if headerFields[freeBlocksCol] != "free" {
return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapsCommand, headerFields[freeBlocksCol], "free")
return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapCommand, headerFields[freeBlocksCol], "free")
}
var swapDevices []*SwapDevice
@ -181,17 +180,17 @@ func parseSwapsCommandOutput(output string) ([]*SwapDevice, error) {
}
fields := strings.Fields(line)
if len(fields) < freeBlocksCol {
return nil, fmt.Errorf("couldn't parse %q: too few fields", swapsCommand)
return nil, fmt.Errorf("couldn't parse %q: too few fields", swapCommand)
}
totalBlocks, err := strconv.ParseUint(fields[totalBlocksCol], 10, 64)
if err != nil {
return nil, fmt.Errorf("couldn't parse 'Size' column in %q: %w", swapsCommand, err)
return nil, fmt.Errorf("couldn't parse 'Size' column in %q: %w", swapCommand, err)
}
freeBlocks, err := strconv.ParseUint(fields[freeBlocksCol], 10, 64)
if err != nil {
return nil, fmt.Errorf("couldn't parse 'Used' column in %q: %w", swapsCommand, err)
return nil, fmt.Errorf("couldn't parse 'Used' column in %q: %w", swapCommand, err)
}
swapDevices = append(swapDevices, &SwapDevice{

@ -116,51 +116,51 @@ type processBasicInformation64 struct {
}
type processEnvironmentBlock32 struct {
Reserved1 [2]uint8
BeingDebugged uint8
Reserved2 uint8
Reserved3 [2]uint32
Ldr uint32
Reserved1 [2]uint8
BeingDebugged uint8
Reserved2 uint8
Reserved3 [2]uint32
Ldr uint32
ProcessParameters uint32
// More fields which we don't use so far
}
type processEnvironmentBlock64 struct {
Reserved1 [2]uint8
BeingDebugged uint8
Reserved2 uint8
_ [4]uint8 // padding, since we are 64 bit, the next pointer is 64 bit aligned (when compiling for 32 bit, this is not the case without manual padding)
Reserved3 [2]uint64
Ldr uint64
Reserved1 [2]uint8
BeingDebugged uint8
Reserved2 uint8
_ [4]uint8 // padding, since we are 64 bit, the next pointer is 64 bit aligned (when compiling for 32 bit, this is not the case without manual padding)
Reserved3 [2]uint64
Ldr uint64
ProcessParameters uint64
// More fields which we don't use so far
}
type rtlUserProcessParameters32 struct {
Reserved1 [16]uint8
Reserved2 [10]uint32
Reserved1 [16]uint8
Reserved2 [10]uint32
ImagePathNameLength uint16
_ uint16
ImagePathAddress uint32
CommandLineLength uint16
_ uint16
CommandLineAddress uint32
EnvironmentAddress uint32
_ uint16
ImagePathAddress uint32
CommandLineLength uint16
_ uint16
CommandLineAddress uint32
EnvironmentAddress uint32
// More fields which we don't use so far
}
type rtlUserProcessParameters64 struct {
Reserved1 [16]uint8
Reserved2 [10]uint64
Reserved1 [16]uint8
Reserved2 [10]uint64
ImagePathNameLength uint16
_ uint16 // Max Length
_ uint32 // Padding
ImagePathAddress uint64
CommandLineLength uint16
_ uint16 // Max Length
_ uint32 // Padding
CommandLineAddress uint64
EnvironmentAddress uint64
_ uint16 // Max Length
_ uint32 // Padding
ImagePathAddress uint64
CommandLineLength uint16
_ uint16 // Max Length
_ uint32 // Padding
CommandLineAddress uint64
EnvironmentAddress uint64
// More fields which we don't use so far
}
@ -669,7 +669,10 @@ func (p *Process) TerminateWithContext(ctx context.Context) error {
}
func (p *Process) KillWithContext(ctx context.Context) error {
process := os.Process{Pid: int(p.Pid)}
process, err := os.FindProcess(int(p.Pid))
if err != nil {
return err
}
return process.Kill()
}
@ -928,14 +931,14 @@ func getProcessEnvironmentVariables(pid int32, ctx context.Context) ([]string, e
is32BitProcess: procIs32Bits,
offset: processParameterBlockAddress,
})
envvarScanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error){
envvarScanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
// Check for UTF-16 zero character
for i := 0; i < len(data) - 1; i+=2 {
for i := 0; i < len(data)-1; i += 2 {
if data[i] == 0 && data[i+1] == 0 {
return i+2, data[0:i], nil
return i + 2, data[0:i], nil
}
}
if atEOF {
@ -965,9 +968,9 @@ func getProcessEnvironmentVariables(pid int32, ctx context.Context) ([]string, e
}
type processReader struct {
processHandle windows.Handle
processHandle windows.Handle
is32BitProcess bool
offset uint64
offset uint64
}
func (p *processReader) Read(buf []byte) (int, error) {

@ -0,0 +1,104 @@
//go:build windows && arm64
// +build windows,arm64
package process
import (
"errors"
"syscall"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
)
type PROCESS_MEMORY_COUNTERS struct {
CB uint32
PageFaultCount uint32
PeakWorkingSetSize uint32
WorkingSetSize uint32
QuotaPeakPagedPoolUsage uint32
QuotaPagedPoolUsage uint32
QuotaPeakNonPagedPoolUsage uint32
QuotaNonPagedPoolUsage uint32
PagefileUsage uint32
PeakPagefileUsage uint32
}
func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) (uint64, error) {
if is32BitProcess {
//we are on a 32-bit process reading an external 32-bit process
var info processBasicInformation32
ret, _, _ := common.ProcNtQueryInformationProcess.Call(
uintptr(procHandle),
uintptr(common.ProcessBasicInformation),
uintptr(unsafe.Pointer(&info)),
uintptr(unsafe.Sizeof(info)),
uintptr(0),
)
if int(ret) >= 0 {
return uint64(info.PebBaseAddress), nil
}
} else {
//we are on a 32-bit process reading an external 64-bit process
if common.ProcNtWow64QueryInformationProcess64.Find() == nil { //avoid panic
var info processBasicInformation64
ret, _, _ := common.ProcNtWow64QueryInformationProcess64.Call(
uintptr(procHandle),
uintptr(common.ProcessBasicInformation),
uintptr(unsafe.Pointer(&info)),
uintptr(unsafe.Sizeof(info)),
uintptr(0),
)
if int(ret) >= 0 {
return info.PebBaseAddress, nil
}
}
}
//return 0 on error
return 0, errors.New("could not query PEB address")
}
func readProcessMemory(h syscall.Handle, is32BitProcess bool, address uint64, size uint) []byte {
if is32BitProcess {
var read uint
buffer := make([]byte, size)
ret, _, _ := common.ProcNtReadVirtualMemory.Call(
uintptr(h),
uintptr(address),
uintptr(unsafe.Pointer(&buffer[0])),
uintptr(size),
uintptr(unsafe.Pointer(&read)),
)
if int(ret) >= 0 && read > 0 {
return buffer[:read]
}
} else {
//reading a 64-bit process from a 32-bit one
if common.ProcNtWow64ReadVirtualMemory64.Find() == nil { //avoid panic
var read uint64
buffer := make([]byte, size)
ret, _, _ := common.ProcNtWow64ReadVirtualMemory64.Call(
uintptr(h),
uintptr(address&0xFFFFFFFF), //the call expects a 64-bit value
uintptr(address>>32),
uintptr(unsafe.Pointer(&buffer[0])),
uintptr(size), //the call expects a 64-bit value
uintptr(0), //but size is 32-bit so pass zero as the high dword
uintptr(unsafe.Pointer(&read)),
)
if int(ret) >= 0 && read > 0 {
return buffer[:uint(read)]
}
}
}
//if we reach here, an error happened
return nil
}

@ -5,8 +5,9 @@ go 1.15
require (
github.com/StackExchange/wmi v1.2.1
github.com/google/go-cmp v0.5.6
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0
github.com/stretchr/testify v1.7.0
github.com/tklauser/go-sysconf v0.3.9
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c
)

@ -2,8 +2,9 @@ github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDO
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
@ -22,9 +23,9 @@ github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ
github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ=
github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71 h1:ikCpsnYR+Ew0vu99XlDp55lGgDJdIMx3f4a18jfse/s=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c h1:taxlMj0D/1sOAuv/CbSD+MMDof2vbyPTqz5FNYKpXt8=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

@ -4,7 +4,6 @@ package mem
import (
"context"
"errors"
"fmt"
"os/exec"
"regexp"
@ -68,7 +67,7 @@ func zoneName() (string, error) {
return strings.TrimSpace(string(out)), nil
}
var globalZoneMemoryCapacityMatch = regexp.MustCompile(`memory size: ([\d]+) Megabytes`)
var globalZoneMemoryCapacityMatch = regexp.MustCompile(`[Mm]emory size: (\d+) Megabytes`)
func globalZoneMemoryCapacity() (uint64, error) {
prtconf, err := exec.LookPath("prtconf")
@ -84,7 +83,7 @@ func globalZoneMemoryCapacity() (uint64, error) {
match := globalZoneMemoryCapacityMatch.FindAllStringSubmatch(string(out), -1)
if len(match) != 1 {
return 0, errors.New("memory size not contained in output of /usr/sbin/prtconf")
return 0, fmt.Errorf("memory size not contained in output of %q", prtconf)
}
totalMB, err := strconv.ParseUint(match[0][1], 10, 64)
@ -95,7 +94,7 @@ func globalZoneMemoryCapacity() (uint64, error) {
return totalMB * 1024 * 1024, nil
}
var kstatMatch = regexp.MustCompile(`([^\s]+)[\s]+([^\s]*)`)
var kstatMatch = regexp.MustCompile(`(\S+)\s+(\S*)`)
func nonGlobalZoneMemoryCapacity() (uint64, error) {
kstat, err := exec.LookPath("kstat")
@ -122,7 +121,7 @@ func nonGlobalZoneMemoryCapacity() (uint64, error) {
return memSizeBytes, nil
}
const swapsCommand = "swap"
const swapCommand = "swap"
// The blockSize as reported by `swap -l`. See https://docs.oracle.com/cd/E23824_01/html/821-1459/fsswap-52195.html
const blockSize = 512
@ -141,13 +140,13 @@ func SwapDevices() ([]*SwapDevice, error) {
}
func SwapDevicesWithContext(ctx context.Context) ([]*SwapDevice, error) {
swapsCommandPath, err := exec.LookPath(swapsCommand)
swapCommandPath, err := exec.LookPath(swapCommand)
if err != nil {
return nil, fmt.Errorf("could not find command %q: %w", swapsCommand, err)
return nil, fmt.Errorf("could not find command %q: %w", swapCommand, err)
}
output, err := invoke.CommandWithContext(ctx, swapsCommandPath, "-l")
output, err := invoke.CommandWithContext(ctx, swapCommandPath, "-l")
if err != nil {
return nil, fmt.Errorf("could not execute %q: %w", swapsCommand, err)
return nil, fmt.Errorf("could not execute %q: %w", swapCommand, err)
}
return parseSwapsCommandOutput(string(output))
@ -156,22 +155,22 @@ func SwapDevicesWithContext(ctx context.Context) ([]*SwapDevice, error) {
func parseSwapsCommandOutput(output string) ([]*SwapDevice, error) {
lines := strings.Split(output, "\n")
if len(lines) == 0 {
return nil, fmt.Errorf("could not parse output of %q: no lines in %q", swapsCommand, output)
return nil, fmt.Errorf("could not parse output of %q: no lines in %q", swapCommand, output)
}
// Check header headerFields are as expected.
headerFields := strings.Fields(lines[0])
if len(headerFields) < freeBlocksCol {
return nil, fmt.Errorf("couldn't parse %q: too few fields in header %q", swapsCommand, lines[0])
return nil, fmt.Errorf("couldn't parse %q: too few fields in header %q", swapCommand, lines[0])
}
if headerFields[nameCol] != "swapfile" {
return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapsCommand, headerFields[nameCol], "swapfile")
return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapCommand, headerFields[nameCol], "swapfile")
}
if headerFields[totalBlocksCol] != "blocks" {
return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapsCommand, headerFields[totalBlocksCol], "blocks")
return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapCommand, headerFields[totalBlocksCol], "blocks")
}
if headerFields[freeBlocksCol] != "free" {
return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapsCommand, headerFields[freeBlocksCol], "free")
return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapCommand, headerFields[freeBlocksCol], "free")
}
var swapDevices []*SwapDevice
@ -181,17 +180,17 @@ func parseSwapsCommandOutput(output string) ([]*SwapDevice, error) {
}
fields := strings.Fields(line)
if len(fields) < freeBlocksCol {
return nil, fmt.Errorf("couldn't parse %q: too few fields", swapsCommand)
return nil, fmt.Errorf("couldn't parse %q: too few fields", swapCommand)
}
totalBlocks, err := strconv.ParseUint(fields[totalBlocksCol], 10, 64)
if err != nil {
return nil, fmt.Errorf("couldn't parse 'Size' column in %q: %w", swapsCommand, err)
return nil, fmt.Errorf("couldn't parse 'Size' column in %q: %w", swapCommand, err)
}
freeBlocks, err := strconv.ParseUint(fields[freeBlocksCol], 10, 64)
if err != nil {
return nil, fmt.Errorf("couldn't parse 'Used' column in %q: %w", swapsCommand, err)
return nil, fmt.Errorf("couldn't parse 'Used' column in %q: %w", swapCommand, err)
}
swapDevices = append(swapDevices, &SwapDevice{

@ -1,15 +1,18 @@
// +build !darwin,!linux,!freebsd,!openbsd,!windows,!solaris
// +build !darwin,!linux,!freebsd,!openbsd,!windows,!solaris,!plan9
package process
import (
"context"
"syscall"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/shirou/gopsutil/v3/net"
)
type Signal = syscall.Signal
type MemoryMapsStat struct {
Path string `json:"path"`
Rss uint64 `json:"rss"`

@ -3,7 +3,205 @@
package process
import (
"context"
"syscall"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/internal/common"
"github.com/shirou/gopsutil/v3/net"
)
type Signal = syscall.Note
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 nil, common.ErrNotImplementedError
}
func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
return nil, common.ErrNotImplementedError
}
func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
return false, common.ErrNotImplementedError
}
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) {
return "", common.ErrNotImplementedError
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
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) {
return 0, common.ErrNotImplementedError
}
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
}
func (p *Process) SendSignalWithContext(ctx context.Context, sig Signal) error {
return common.ErrNotImplementedError
}
func (p *Process) SuspendWithContext(ctx context.Context) error {
return common.ErrNotImplementedError
}
func (p *Process) ResumeWithContext(ctx context.Context) error {
return common.ErrNotImplementedError
}
func (p *Process) TerminateWithContext(ctx context.Context) error {
return common.ErrNotImplementedError
}
func (p *Process) KillWithContext(ctx context.Context) error {
return common.ErrNotImplementedError
}
func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) EnvironWithContext(ctx context.Context) ([]string, error) {
return nil, common.ErrNotImplementedError
}

@ -82,7 +82,7 @@ func isMount(path string) bool {
if err != nil {
return false
}
if fileInfo.Mode() & os.ModeSymlink != 0 {
if fileInfo.Mode()&os.ModeSymlink != 0 {
return false
}
var stat1 unix.Stat_t

Loading…
Cancel
Save