diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 82970db..7ecac03 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,10 +29,3 @@ jobs: - name: Test run: | go test -coverprofile='coverage.out' -covermode=atomic ./... - - name: Upload Code Coverage - uses: codecov/codecov-action@v2 - with: - fail_ci_if_error: true - files: coverage.out - flags: ${{ runner.os }},go-${{ matrix.go-version }} - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/LICENSE b/LICENSE index da71a5e..6f06adc 100644 --- a/LICENSE +++ b/LICENSE @@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------- -internal/common/binary.go in the gopsutil is copied and modifid from golang/encoding/binary.go. +internal/common/binary.go in the gopsutil is copied and modified from golang/encoding/binary.go. diff --git a/README.md b/README.md index f66413b..191f3c7 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ challenge is porting all psutil functions on some architectures. ## v3 migration -from v3.20.10, gopsutil becomes v3 which breaks backwards compatiblity. +from v3.20.10, gopsutil becomes v3 which breaks backwards compatibility. See [v3Changes.md](_tools/v3migration/v3Changes.md) more detail changes. ## Tag semantics @@ -21,7 +21,7 @@ for example, v2.17.04 means - 17: release year, 2017 - 04: release month -gopsutil aims to keep backwards-compatiblity until major version change. +gopsutil aims to keep backwards compatibility until major version change. Tagged at every end of month, but if there are only a few commits, it can be skipped. @@ -130,7 +130,7 @@ will provide useful information. - CacheSize - Flags (ex: "fpu vme de pse tsc msr pae mce cx8 ...") - Microcode -- load/LoadAvg() (linux, freebsd) +- load/Avg() (linux, freebsd, solaris) - Load1 - Load5 - Load15 @@ -229,7 +229,7 @@ Some code is ported from Ohai. many thanks. |**HostInfo** | | | | | | | |hostname |x |x |x |x |x |x | |uptime |x |x |x |x | |x | -|proces |x |x |x | | |x | +|process |x |x |x | | |x | |os |x |x |x |x |x |x | |platform |x |x |x |x | |x | |platformfamily |x |x |x |x | |x | diff --git a/disk/disk_freebsd.go b/disk/disk_freebsd.go index e74c186..8f4ede5 100644 --- a/disk/disk_freebsd.go +++ b/disk/disk_freebsd.go @@ -4,10 +4,14 @@ package disk import ( + "bufio" "bytes" "context" "encoding/binary" + "fmt" + "os/exec" "strconv" + "strings" "golang.org/x/sys/unix" @@ -163,7 +167,29 @@ func getFsType(stat unix.Statfs_t) string { } func SerialNumberWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError + geom, err := exec.LookPath("geom") + if err != nil { + return "", fmt.Errorf("find geom: %w", err) + } + geomOut, err := invoke.CommandWithContext(ctx, geom, "disk", "list", name) + if err != nil { + return "", fmt.Errorf("exec geom: %w", err) + } + s := bufio.NewScanner(bytes.NewReader(geomOut)) + serial := "" + for s.Scan() { + flds := strings.Fields(s.Text()) + if len(flds) == 2 && flds[0] == "ident:" { + if flds[1] != "(null)" { + serial = flds[1] + } + break + } + } + if err = s.Err(); err != nil { + return "", err + } + return serial, nil } func LabelWithContext(ctx context.Context, name string) (string, error) { diff --git a/docker/docker_linux.go b/docker/docker_linux.go index beaf96e..4c5d152 100644 --- a/docker/docker_linux.go +++ b/docker/docker_linux.go @@ -57,7 +57,7 @@ func GetDockerStatWithContext(ctx context.Context) ([]CgroupDockerStat, error) { return ret, nil } -// GetDockerIDList returnes a list of DockerID. +// GetDockerIDList returns a list of DockerID. // This requires certain permission. func GetDockerIDList() ([]string, error) { return GetDockerIDListWithContext(context.Background()) @@ -86,7 +86,7 @@ func GetDockerIDListWithContext(ctx context.Context) ([]string, error) { return ret, nil } -// CgroupCPU returnes specified cgroup id CPU status. +// CgroupCPU returns specified cgroup id CPU status. // containerID is same as docker id if you use docker. // If you use container via systemd.slice, you could use // containerID = docker-.scope and base=/sys/fs/cgroup/cpuacct/system.slice/ @@ -94,7 +94,7 @@ func CgroupCPU(containerID string, base string) (*CgroupCPUStat, error) { return CgroupCPUWithContext(context.Background(), containerID, base) } -// CgroupCPUUsage returnes specified cgroup id CPU usage. +// CgroupCPUUsage returns specified cgroup id CPU usage. // containerID is same as docker id if you use docker. // If you use container via systemd.slice, you could use // containerID = docker-.scope and base=/sys/fs/cgroup/cpuacct/system.slice/ diff --git a/docker/docker_notlinux.go b/docker/docker_notlinux.go index df33512..2bd9111 100644 --- a/docker/docker_notlinux.go +++ b/docker/docker_notlinux.go @@ -19,7 +19,7 @@ func GetDockerStatWithContext(ctx context.Context) ([]CgroupDockerStat, error) { return nil, ErrDockerNotAvailable } -// GetDockerIDList returnes a list of DockerID. +// GetDockerIDList returns a list of DockerID. // This requires certain permission. func GetDockerIDList() ([]string, error) { return GetDockerIDListWithContext(context.Background()) @@ -29,7 +29,7 @@ func GetDockerIDListWithContext(ctx context.Context) ([]string, error) { return nil, ErrDockerNotAvailable } -// CgroupCPU returnes specified cgroup id CPU status. +// CgroupCPU returns specified cgroup id CPU status. // containerid is same as docker id if you use docker. // If you use container via systemd.slice, you could use // containerid = docker-.scope and base=/sys/fs/cgroup/cpuacct/system.slice/ diff --git a/go.mod b/go.mod index f19cec5..cd19839 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,11 @@ module github.com/shirou/gopsutil/v3 go 1.15 require ( - github.com/google/go-cmp v0.5.6 + github.com/google/go-cmp v0.5.7 github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c github.com/stretchr/testify v1.7.0 github.com/tklauser/go-sysconf v0.3.9 github.com/yusufpapurcu/wmi v1.2.2 - golang.org/x/sys v0.0.0-20211013075003-97ac67df715c + golang.org/x/sys v0.0.0-20220111092808-5a964db01320 ) diff --git a/go.sum b/go.sum index 50b5a10..0b2f058 100644 --- a/go.sum +++ b/go.sum @@ -2,12 +2,11 @@ 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.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= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -26,8 +25,8 @@ github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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/sys v0.0.0-20220111092808-5a964db01320 h1:0jf+tOCoZ3LyutmCOWpVni1chK4VfFLhRsDK7MhqGRY= +golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 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= diff --git a/host/host_linux.go b/host/host_linux.go index 29ad9ab..def9a67 100644 --- a/host/host_linux.go +++ b/host/host_linux.go @@ -283,7 +283,7 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil family = "debian" case "fedora": family = "fedora" - case "oracle", "centos", "redhat", "scientific", "enterpriseenterprise", "amazon", "xenserver", "cloudlinux", "ibm_powerkvm", "rocky": + case "oracle", "centos", "redhat", "scientific", "enterpriseenterprise", "amazon", "xenserver", "cloudlinux", "ibm_powerkvm", "rocky", "almalinux": family = "rhel" case "suse", "opensuse", "opensuse-leap", "opensuse-tumbleweed", "opensuse-tumbleweed-kubic", "sles", "sled", "caasp": family = "suse" diff --git a/internal/common/common.go b/internal/common/common.go index 9bfb366..4f6df9a 100644 --- a/internal/common/common.go +++ b/internal/common/common.go @@ -64,7 +64,7 @@ func (i Invoke) CommandWithContext(ctx context.Context, name string, arg ...stri type FakeInvoke struct { Suffix string // Suffix species expected file name suffix such as "fail" - Error error // If Error specfied, return the error. + Error error // If Error specified, return the error. } // Command in FakeInvoke returns from expected file if exists. diff --git a/internal/common/common_linux.go b/internal/common/common_linux.go index 95d4ebd..0f7b40c 100644 --- a/internal/common/common_linux.go +++ b/internal/common/common_linux.go @@ -100,8 +100,9 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) { if err != nil { return 0, err } - t := uint64(time.Now().Unix()) - uint64(b) - return t, nil + currentTime := float64(time.Now().UnixNano()) / float64(time.Second) + t := currentTime - b + return uint64(t), nil } return 0, fmt.Errorf("could not find btime") diff --git a/load/load_darwin.go b/load/load_darwin.go index 73e62ca..e0df3c9 100644 --- a/load/load_darwin.go +++ b/load/load_darwin.go @@ -39,7 +39,7 @@ func AvgWithContext(ctx context.Context) (*AvgStat, error) { return ret, nil } -// Misc returnes miscellaneous host-wide statistics. +// Misc returns miscellaneous host-wide statistics. // darwin use ps command to get process running/blocked count. // Almost same as FreeBSD implementation, but state is different. // U means 'Uninterruptible Sleep'. diff --git a/load/load_linux.go b/load/load_linux.go index 30bba35..debf073 100644 --- a/load/load_linux.go +++ b/load/load_linux.go @@ -68,7 +68,7 @@ func fileAvgWithContext() (*AvgStat, error) { return ret, nil } -// Misc returnes miscellaneous host-wide statistics. +// Misc returns miscellaneous host-wide statistics. // Note: the name should be changed near future. func Misc() (*MiscStat, error) { return MiscWithContext(context.Background()) diff --git a/load/load_solaris.go b/load/load_solaris.go index b9dd273..aa6cd1e 100644 --- a/load/load_solaris.go +++ b/load/load_solaris.go @@ -4,11 +4,12 @@ package load import ( + "bufio" + "bytes" "context" "os/exec" + "strconv" "strings" - - "github.com/shirou/gopsutil/v3/internal/common" ) func Avg() (*AvgStat, error) { @@ -16,7 +17,45 @@ func Avg() (*AvgStat, error) { } func AvgWithContext(ctx context.Context) (*AvgStat, error) { - return nil, common.ErrNotImplementedError + kstat, err := exec.LookPath("kstat") + if err != nil { + return nil, err + } + + out, err := invoke.CommandWithContext(ctx, kstat, "-p", "unix:0:system_misc:avenrun_*") + if err != nil { + return nil, err + } + + avg := &AvgStat{} + scanner := bufio.NewScanner(bytes.NewReader(out)) + for scanner.Scan() { + flds := strings.Fields(scanner.Text()) + if len(flds) < 2 { + continue + } + var tgt *float64 + switch { + case strings.HasSuffix(flds[0], ":avenrun_1min"): + tgt = &avg.Load1 + case strings.HasSuffix(flds[0], ":avenrun_5min"): + tgt = &avg.Load5 + case strings.HasSuffix(flds[0], ":avenrun_15min"): + tgt = &avg.Load15 + default: + continue + } + v, err := strconv.ParseInt(flds[1], 10, 64) + if err != nil { + return nil, err + } + *tgt = float64(v) / (1 << 8) + } + if err = scanner.Err(); err != nil { + return nil, err + } + + return avg, nil } func Misc() (*MiscStat, error) { diff --git a/mem/mem_linux.go b/mem/mem_linux.go index cea5400..9a5967c 100644 --- a/mem/mem_linux.go +++ b/mem/mem_linux.go @@ -305,7 +305,7 @@ func fillFromMeminfoWithContext() (*VirtualMemoryStat, *VirtualMemoryExStat, err if !memavail { if activeFile && inactiveFile && sReclaimable { - ret.Available = calcuateAvailVmem(ret, retEx) + ret.Available = calculateAvailVmem(ret, retEx) } else { ret.Available = ret.Cached + ret.Free } @@ -387,10 +387,10 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { return ret, nil } -// calcuateAvailVmem is a fallback under kernel 3.14 where /proc/meminfo does not provide +// calculateAvailVmem is a fallback under kernel 3.14 where /proc/meminfo does not provide // "MemAvailable:" column. It reimplements an algorithm from the link below // https://github.com/giampaolo/psutil/pull/890 -func calcuateAvailVmem(ret *VirtualMemoryStat, retEx *VirtualMemoryExStat) uint64 { +func calculateAvailVmem(ret *VirtualMemoryStat, retEx *VirtualMemoryExStat) uint64 { var watermarkLow uint64 fn := common.HostProc("zoneinfo") diff --git a/net/net_aix.go b/net/net_aix.go index d89db7c..84e3609 100644 --- a/net/net_aix.go +++ b/net/net_aix.go @@ -105,7 +105,7 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, return iocounters, nil } -// NetIOCountersByFile is an method which is added just a compatibility for linux. +// IOCountersByFile exists just for compatibility with Linux. func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { return IOCountersByFileWithContext(context.Background(), pernic, filename) } diff --git a/net/net_darwin.go b/net/net_darwin.go index 9badcf6..ec9ba41 100644 --- a/net/net_darwin.go +++ b/net/net_darwin.go @@ -257,7 +257,7 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, return ret, nil } -// NetIOCountersByFile is an method which is added just a compatibility for linux. +// IOCountersByFile exists just for compatibility with Linux. func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { return IOCountersByFileWithContext(context.Background(), pernic, filename) } diff --git a/net/net_freebsd.go b/net/net_freebsd.go index 0a30423..50fe93a 100644 --- a/net/net_freebsd.go +++ b/net/net_freebsd.go @@ -95,7 +95,7 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, return ret, nil } -// NetIOCountersByFile is an method which is added just a compatibility for linux. +// IOCountersByFile exists just for compatibility with Linux. func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { return IOCountersByFileWithContext(context.Background(), pernic, filename) } diff --git a/net/net_linux.go b/net/net_linux.go index 291eabf..81cde81 100644 --- a/net/net_linux.go +++ b/net/net_linux.go @@ -40,7 +40,7 @@ const ( // Conntrack Column numbers ctSEARCH_RESTART ) -// NetIOCounters returnes network I/O statistics for every network +// NetIOCounters returns network I/O statistics for every network // interface installed on the system. If pernic argument is false, // return only sum of all information (which name is 'all'). If true, // every network interface installed on the system is returned @@ -188,7 +188,7 @@ func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoC line := lines[i] r := strings.IndexRune(line, ':') if r == -1 { - return nil, errors.New(filename + " is not fomatted correctly, expected ':'.") + return nil, errors.New(filename + " is not formatted correctly, expected ':'.") } proto := strings.ToLower(line[:r]) if !protos[proto] { @@ -204,7 +204,7 @@ func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoC i++ statValues := strings.Split(lines[i][r+2:], " ") if len(statNames) != len(statValues) { - return nil, errors.New(filename + " is not fomatted correctly, expected same number of columns.") + return nil, errors.New(filename + " is not formatted correctly, expected same number of columns.") } stat := ProtoCountersStat{ Protocol: proto, @@ -543,7 +543,7 @@ func statsFromInodesWithContext(ctx context.Context, root string, pid int32, tma return ret, nil } -// getProcInodes returnes fd of the pid. +// getProcInodes returns fd of the pid. func getProcInodes(root string, pid int32, max int) (map[string][]inodeMap, error) { ret := make(map[string][]inodeMap) @@ -553,7 +553,7 @@ func getProcInodes(root string, pid int32, max int) (map[string][]inodeMap, erro return ret, err } defer f.Close() - dirEntries, err := f.ReadDir(max) + dirEntries, err := readDir(f, max) if err != nil { return ret, err } diff --git a/net/net_linux_111.go b/net/net_linux_111.go new file mode 100644 index 0000000..bd5c958 --- /dev/null +++ b/net/net_linux_111.go @@ -0,0 +1,12 @@ +//go:build !go1.16 +// +build !go1.16 + +package net + +import ( + "os" +) + +func readDir(f *os.File, max int) ([]os.FileInfo, error) { + return f.Readdir(max) +} diff --git a/net/net_linux_116.go b/net/net_linux_116.go new file mode 100644 index 0000000..a45072e --- /dev/null +++ b/net/net_linux_116.go @@ -0,0 +1,12 @@ +//go:build go1.16 +// +build go1.16 + +package net + +import ( + "os" +) + +func readDir(f *os.File, max int) ([]os.DirEntry, error) { + return f.ReadDir(max) +} diff --git a/net/net_openbsd.go b/net/net_openbsd.go index 04b9b1d..5f066a0 100644 --- a/net/net_openbsd.go +++ b/net/net_openbsd.go @@ -139,7 +139,7 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, return ret, nil } -// NetIOCountersByFile is an method which is added just a compatibility for linux. +// IOCountersByFile exists just for compatibility with Linux. func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { return IOCountersByFileWithContext(context.Background(), pernic, filename) } diff --git a/net/net_windows.go b/net/net_windows.go index f742d82..731c8f9 100644 --- a/net/net_windows.go +++ b/net/net_windows.go @@ -200,7 +200,7 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, return counters, nil } -// NetIOCountersByFile is an method which is added just a compatibility for linux. +// IOCountersByFile exists just for compatibility with Linux. func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { return IOCountersByFileWithContext(context.Background(), pernic, filename) } diff --git a/process/process.go b/process/process.go index bcfd616..0ca26c2 100644 --- a/process/process.go +++ b/process/process.go @@ -47,13 +47,13 @@ type Process struct { const ( // Running marks a task a running or runnable (on the run queue) Running = "running" - // Blocked marks a task waiting on a short, uninterruptable operation (usually IO) + // Blocked marks a task waiting on a short, uninterruptible operation (usually I/O) Blocked = "blocked" // Idle marks a task sleeping for more than about 20 seconds Idle = "idle" // Lock marks a task waiting to acquire a lock Lock = "lock" - // Sleep marks task waiting for short, interruptable operation + // Sleep marks task waiting for short, interruptible operation Sleep = "sleep" // Stop marks a stopped process Stop = "stop" @@ -230,7 +230,7 @@ func (p *Process) BackgroundWithContext(ctx context.Context) (bool, error) { } // If interval is 0, return difference from last call(non-blocking). -// If interval > 0, wait interval sec and return diffrence between start and end. +// If interval > 0, wait interval sec and return difference between start and end. func (p *Process) Percent(interval time.Duration) (float64, error) { return p.PercentWithContext(context.Background(), interval) } @@ -402,6 +402,15 @@ func (p *Process) Parent() (*Process, error) { return p.ParentWithContext(context.Background()) } +// ParentWithContext returns parent Process of the process. +func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { + ppid, err := p.PpidWithContext(ctx) + if err != nil { + return nil, err + } + return NewProcessWithContext(ctx, ppid) +} + // Status returns the process status. // Return value could be one of these. // R: Running S: Sleep T: Stop I: Idle diff --git a/process/process_darwin.go b/process/process_darwin.go index c1dc918..7c72417 100644 --- a/process/process_darwin.go +++ b/process/process_darwin.go @@ -10,9 +10,7 @@ import ( "path/filepath" "strconv" "strings" - "time" - "github.com/shirou/gopsutil/v3/cpu" "github.com/shirou/gopsutil/v3/internal/common" "github.com/shirou/gopsutil/v3/net" "github.com/tklauser/go-sysconf" @@ -46,34 +44,25 @@ type _Ctype_struct___0 struct { func pidsWithContext(ctx context.Context) ([]int32, error) { var ret []int32 - pids, err := callPsWithContext(ctx, "pid", 0, false, false) + kprocs, err := unix.SysctlKinfoProcSlice("kern.proc.all") if err != nil { return ret, err } - for _, pid := range pids { - v, err := strconv.Atoi(pid[0]) - if err != nil { - return ret, err - } - ret = append(ret, int32(v)) + for _, proc := range kprocs { + ret = append(ret, int32(proc.Proc.P_pid)) } return ret, nil } func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { - r, err := callPsWithContext(ctx, "ppid", p.Pid, false, false) - if err != nil { - return 0, err - } - - v, err := strconv.Atoi(r[0][0]) + k, err := p.getKProc() if err != nil { return 0, err } - return int32(v), err + return k.Eproc.Ppid, nil } func (p *Process) NameWithContext(ctx context.Context) (string, error) { @@ -81,7 +70,8 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { if err != nil { return "", err } - name := common.IntToString(k.Proc.P_comm[:]) + + name := common.ByteToString(k.Proc.P_comm[:]) if len(name) >= 15 { cmdName, err := p.cmdNameWithContext(ctx) @@ -89,11 +79,11 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { return "", err } if len(cmdName) > 0 { - extendedName := filepath.Base(cmdName[0]) + extendedName := filepath.Base(cmdName) if strings.HasPrefix(extendedName, p.name) { name = extendedName } else { - name = cmdName[0] + name = cmdName } } } @@ -101,61 +91,13 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { return name, nil } -// 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 -} - func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { - r, err := callPsWithContext(ctx, "etime", p.Pid, false, false) + k, err := p.getKProc() if err != nil { return 0, err } - elapsedSegments := strings.Split(strings.Replace(r[0][0], "-", ":", 1), ":") - var elapsedDurations []time.Duration - for i := len(elapsedSegments) - 1; i >= 0; i-- { - p, err := strconv.ParseInt(elapsedSegments[i], 10, 0) - if err != nil { - return 0, err - } - elapsedDurations = append(elapsedDurations, time.Duration(p)) - } - - elapsed := time.Duration(elapsedDurations[0]) * time.Second - if len(elapsedDurations) > 1 { - elapsed += time.Duration(elapsedDurations[1]) * time.Minute - } - if len(elapsedDurations) > 2 { - elapsed += time.Duration(elapsedDurations[2]) * time.Hour - } - if len(elapsedDurations) > 3 { - elapsed += time.Duration(elapsedDurations[3]) * time.Hour * 24 - } - - start := time.Now().Add(-elapsed) - return start.Unix() * 1000, nil -} - -func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { - out, err := common.CallLsofWithContext(ctx, invoke, p.Pid, "-FR") - if err != nil { - return nil, err - } - 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)) - } - } - return nil, fmt.Errorf("could not find parent line") + return k.Proc.P_starttime.Sec*1000 + int64(k.Proc.P_starttime.Usec)/1000, nil } func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { @@ -188,7 +130,7 @@ func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { } // See: http://unix.superglobalmegacorp.com/Net2/newsrc/sys/ucred.h.html - userEffectiveUID := int32(k.Eproc.Ucred.UID) + userEffectiveUID := int32(k.Eproc.Ucred.Uid) return []int32{userEffectiveUID}, nil } @@ -200,7 +142,7 @@ func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { } gids := make([]int32, 0, 3) - gids = append(gids, int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Ucred.Ngroups), int32(k.Eproc.Pcred.P_svgid)) + gids = append(gids, int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Pcred.P_svgid)) return gids, nil } @@ -250,14 +192,6 @@ func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, e return nil, common.ErrNotImplementedError } -func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { - r, err := callPsWithContext(ctx, "utime,stime", p.Pid, true, false) - if err != nil { - return 0, err - } - return int32(len(r)), nil -} - func convertCPUTimes(s string) (ret float64, err error) { var t int var _tmp string @@ -304,56 +238,6 @@ func convertCPUTimes(s string) (ret float64, err error) { 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, false) - if err != nil { - return nil, err - } - - utime, err := convertCPUTimes(r[0][0]) - if err != nil { - return nil, err - } - stime, err := convertCPUTimes(r[0][1]) - if err != nil { - return nil, err - } - - ret := &cpu.TimesStat{ - CPU: "cpu", - User: utime, - System: stime, - } - return ret, nil -} - -func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { - r, err := callPsWithContext(ctx, "rss,vsize,pagein", p.Pid, false, false) - if err != nil { - return nil, err - } - rss, err := strconv.Atoi(r[0][0]) - if err != nil { - return nil, err - } - vms, err := strconv.Atoi(r[0][1]) - if err != nil { - return nil, err - } - pagein, err := strconv.Atoi(r[0][2]) - if err != nil { - return nil, err - } - - ret := &MemoryInfoStat{ - RSS: uint64(rss) * 1024, - VMS: uint64(vms) * 1024, - Swap: uint64(pagein), - } - - return ret, nil -} - func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid) if err != nil { @@ -399,17 +283,8 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) { // Returns a proc as defined here: // http://unix.superglobalmegacorp.com/Net2/newsrc/sys/kinfo_proc.h.html -func (p *Process) getKProc() (*KinfoProc, error) { - buf, err := unix.SysctlRaw("kern.proc.pid", int(p.Pid)) - if err != nil { - return nil, err - } - k, err := parseKinfoProc(buf) - if err != nil { - return nil, err - } - - return &k, nil +func (p *Process) getKProc() (*unix.KinfoProc, error) { + return unix.SysctlKinfoProc("kern.proc.pid", int(p.Pid)) } // call ps command. diff --git a/process/process_darwin_cgo.go b/process/process_darwin_cgo.go index 972b74b..2ac413f 100644 --- a/process/process_darwin_cgo.go +++ b/process/process_darwin_cgo.go @@ -9,6 +9,7 @@ package process // #include // #include // #include +// #include import "C" import ( @@ -18,12 +19,18 @@ import ( "strings" "syscall" "unsafe" + + "github.com/shirou/gopsutil/v3/cpu" ) -var argMax int +var ( + argMax int + timescaleToNanoSeconds float64 +) func init() { argMax = getArgMax() + timescaleToNanoSeconds = getTimeScaleToNanoSeconds() } func getArgMax() int { @@ -39,6 +46,14 @@ func getArgMax() int { return 0 } +func getTimeScaleToNanoSeconds() float64 { + var timeBaseInfo C.struct_mach_timebase_info + + C.mach_timebase_info(&timeBaseInfo) + + return float64(timeBaseInfo.numer) / float64(timeBaseInfo.denom) +} + func (p *Process) ExeWithContext(ctx context.Context) (string, error) { var c C.char // need a var for unsafe.Sizeof need a var const bufsize = C.PROC_PIDPATHINFO_MAXSIZE * unsafe.Sizeof(c) @@ -82,7 +97,7 @@ func (p *Process) CwdWithContext(ctx context.Context) (string, error) { return C.GoString(&vpi.pvi_cdir.vip_path[0]), err } -func procArgs(pid int32) (*[]byte, int, error) { +func procArgs(pid int32) ([]byte, int, error) { var ( mib = [...]C.int{C.CTL_KERN, C.KERN_PROCARGS2, C.int(pid)} size C.size_t = C.ulong(argMax) @@ -91,23 +106,27 @@ func procArgs(pid int32) (*[]byte, int, error) { ) procargs := (*C.char)(C.malloc(C.ulong(argMax))) defer C.free(unsafe.Pointer(procargs)) - retval := C.sysctl(&mib[0], 3, unsafe.Pointer(procargs), &size, C.NULL, 0) + retval, err := C.sysctl(&mib[0], 3, unsafe.Pointer(procargs), &size, C.NULL, 0) if retval == 0 { C.memcpy(unsafe.Pointer(&nargs), unsafe.Pointer(procargs), C.sizeof_int) result = C.GoBytes(unsafe.Pointer(procargs), C.int(size)) // fmt.Printf("size: %d %d\n%s\n", size, nargs, hex.Dump(result)) - return &result, int(nargs), nil + return result, int(nargs), nil } - return nil, 0, fmt.Errorf("error: %d", retval) + return nil, 0, err } func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { + return p.cmdlineSliceWithContext(ctx, true) +} + +func (p *Process) cmdlineSliceWithContext(ctx context.Context, fallback bool) ([]string, error) { pargs, nargs, err := procArgs(p.Pid) if err != nil { return nil, err } // The first bytes hold the nargs int, skip it. - args := bytes.Split((*pargs)[C.sizeof_int:], []byte{0}) + args := bytes.Split((pargs)[C.sizeof_int:], []byte{0}) var argStr string // The first element is the actual binary/command path. // command := args[0] @@ -131,6 +150,20 @@ func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) return argSlice, err } +// cmdNameWithContext returns the command name (including spaces) without any arguments +func (p *Process) cmdNameWithContext(ctx context.Context) (string, error) { + r, err := p.cmdlineSliceWithContext(ctx, false) + if err != nil { + return "", err + } + + if len(r) == 0 { + return "", nil + } + + return r[0], err +} + func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { r, err := p.CmdlineSliceWithContext(ctx) if err != nil { @@ -138,3 +171,49 @@ func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { } return strings.Join(r, " "), err } + +func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { + const tiSize = C.sizeof_struct_proc_taskinfo + ti := (*C.struct_proc_taskinfo)(C.malloc(tiSize)) + + _, err := C.proc_pidinfo(C.int(p.Pid), C.PROC_PIDTASKINFO, 0, unsafe.Pointer(ti), tiSize) + if err != nil { + return 0, err + } + + return int32(ti.pti_threadnum), nil +} + +func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { + const tiSize = C.sizeof_struct_proc_taskinfo + ti := (*C.struct_proc_taskinfo)(C.malloc(tiSize)) + + _, err := C.proc_pidinfo(C.int(p.Pid), C.PROC_PIDTASKINFO, 0, unsafe.Pointer(ti), tiSize) + if err != nil { + return nil, err + } + + ret := &cpu.TimesStat{ + CPU: "cpu", + User: float64(ti.pti_total_user) * timescaleToNanoSeconds / 1e9, + System: float64(ti.pti_total_system) * timescaleToNanoSeconds / 1e9, + } + return ret, nil +} + +func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { + const tiSize = C.sizeof_struct_proc_taskinfo + ti := (*C.struct_proc_taskinfo)(C.malloc(tiSize)) + + _, err := C.proc_pidinfo(C.int(p.Pid), C.PROC_PIDTASKINFO, 0, unsafe.Pointer(ti), tiSize) + if err != nil { + return nil, err + } + + ret := &MemoryInfoStat{ + RSS: uint64(ti.pti_resident_size), + VMS: uint64(ti.pti_virtual_size), + Swap: uint64(ti.pti_pageins), + } + return ret, nil +} diff --git a/process/process_darwin_nocgo.go b/process/process_darwin_nocgo.go index 1426c97..3d696b7 100644 --- a/process/process_darwin_nocgo.go +++ b/process/process_darwin_nocgo.go @@ -10,6 +10,7 @@ import ( "strconv" "strings" + "github.com/shirou/gopsutil/v3/cpu" "github.com/shirou/gopsutil/v3/internal/common" ) @@ -47,6 +48,18 @@ func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { return strings.Join(r[0], " "), err } +func (p *Process) cmdNameWithContext(ctx context.Context) (string, error) { + r, err := callPsWithContext(ctx, "command", p.Pid, false, true) + if err != nil { + return "", err + } + if len(r) > 0 && len(r[0]) > 0 { + return r[0][0], err + } + + return "", 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 @@ -59,3 +72,61 @@ func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) } return r[0], err } + +func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { + r, err := callPsWithContext(ctx, "utime,stime", p.Pid, true, false) + if err != nil { + return 0, err + } + return int32(len(r)), nil +} + +func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { + r, err := callPsWithContext(ctx, "utime,stime", p.Pid, false, false) + if err != nil { + return nil, err + } + + utime, err := convertCPUTimes(r[0][0]) + if err != nil { + return nil, err + } + stime, err := convertCPUTimes(r[0][1]) + if err != nil { + return nil, err + } + + ret := &cpu.TimesStat{ + CPU: "cpu", + User: utime, + System: stime, + } + return ret, nil +} + +func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { + r, err := callPsWithContext(ctx, "rss,vsize,pagein", p.Pid, false, false) + if err != nil { + return nil, err + } + rss, err := strconv.Atoi(r[0][0]) + if err != nil { + return nil, err + } + vms, err := strconv.Atoi(r[0][1]) + if err != nil { + return nil, err + } + pagein, err := strconv.Atoi(r[0][2]) + if err != nil { + return nil, err + } + + ret := &MemoryInfoStat{ + RSS: uint64(rss) * 1024, + VMS: uint64(vms) * 1024, + Swap: uint64(pagein), + } + + return ret, nil +} diff --git a/process/process_fallback.go b/process/process_fallback.go index e1c4809..1a5d0c4 100644 --- a/process/process_fallback.go +++ b/process/process_fallback.go @@ -74,10 +74,6 @@ 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 } diff --git a/process/process_freebsd.go b/process/process_freebsd.go index a010383..444af35 100644 --- a/process/process_freebsd.go +++ b/process/process_freebsd.go @@ -111,11 +111,11 @@ 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) ParentWithContext(ctx context.Context) (*Process, error) { - return nil, common.ErrNotImplementedError + k, err := p.getKProc() + if err != nil { + return 0, err + } + return k.Start.Sec*1000 + k.Start.Usec/1000, nil } func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { diff --git a/process/process_linux.go b/process/process_linux.go index bff35df..7f6c9f4 100644 --- a/process/process_linux.go +++ b/process/process_linux.go @@ -123,17 +123,6 @@ func (p *Process) CwdWithContext(ctx context.Context) (string, error) { return p.fillFromCwdWithContext() } -func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { - err := p.fillFromStatusWithContext(ctx) - if err != nil { - return nil, err - } - if p.parent == 0 { - return nil, fmt.Errorf("wrong number of parents") - } - return NewProcessWithContext(ctx, p.parent) -} - func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { err := p.fillFromStatusWithContext(ctx) if err != nil { @@ -351,11 +340,11 @@ func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, e func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid) if err != nil { - if len(pids) == 0 { - return nil, ErrorNoChildren - } return nil, err } + if len(pids) == 0 { + return nil, ErrorNoChildren + } ret := make([]*Process, 0, len(pids)) for _, pid := range pids { np, err := NewProcessWithContext(ctx, pid) @@ -537,7 +526,7 @@ func (p *Process) fillFromLimitsWithContext() ([]RlimitStat, error) { // Assert that last item is a Hard limit statItem.Hard, err = limitToUint(str[len(str)-1]) if err != nil { - // On error remove last item an try once again since it can be unit or header line + // On error remove last item and try once again since it can be unit or header line str = str[:len(str)-1] statItem.Hard, err = limitToUint(str[len(str)-1]) if err != nil { diff --git a/process/process_openbsd.go b/process/process_openbsd.go index cdbdaed..77aa804 100644 --- a/process/process_openbsd.go +++ b/process/process_openbsd.go @@ -142,10 +142,6 @@ func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { return 0, common.ErrNotImplementedError } -func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { - return nil, common.ErrNotImplementedError -} - func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { k, err := p.getKProc() if err != nil { diff --git a/process/process_plan9.go b/process/process_plan9.go index 70e11e3..bc4bc06 100644 --- a/process/process_plan9.go +++ b/process/process_plan9.go @@ -74,10 +74,6 @@ 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 } diff --git a/process/process_solaris.go b/process/process_solaris.go index 93a6e01..4f10a67 100644 --- a/process/process_solaris.go +++ b/process/process_solaris.go @@ -88,10 +88,6 @@ 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 } diff --git a/process/process_test.go b/process/process_test.go index 2bb72b8..786eb51 100644 --- a/process/process_test.go +++ b/process/process_test.go @@ -46,26 +46,6 @@ func Test_Pids(t *testing.T) { } } -func Test_Pids_Fail(t *testing.T) { - if runtime.GOOS != "darwin" { - t.Skip("darwin only") - } - - mu.Lock() - defer mu.Unlock() - - invoke = common.FakeInvoke{Suffix: "fail"} - ret, err := Pids() - skipIfNotImplementedErr(t, err) - invoke = common.Invoke{} - if err != nil { - t.Errorf("error %v", err) - } - if len(ret) != 9 { - t.Errorf("wrong getted pid nums: %v/%d", ret, len(ret)) - } -} - func Test_Pid_exists(t *testing.T) { checkPid := os.Getpid() diff --git a/process/process_windows.go b/process/process_windows.go index 282b0d9..d7bb53e 100644 --- a/process/process_windows.go +++ b/process/process_windows.go @@ -189,7 +189,7 @@ type winLUIDAndAttributes struct { } // TOKEN_PRIVILEGES -type winTokenPriviledges struct { +type winTokenPrivileges struct { PrivilegeCount winDWord Privileges [1]winLUIDAndAttributes } @@ -218,23 +218,23 @@ func init() { } defer token.Close() - tokenPriviledges := winTokenPriviledges{PrivilegeCount: 1} + tokenPrivileges := winTokenPrivileges{PrivilegeCount: 1} lpName := syscall.StringToUTF16("SeDebugPrivilege") ret, _, _ := procLookupPrivilegeValue.Call( 0, uintptr(unsafe.Pointer(&lpName[0])), - uintptr(unsafe.Pointer(&tokenPriviledges.Privileges[0].Luid))) + uintptr(unsafe.Pointer(&tokenPrivileges.Privileges[0].Luid))) if ret == 0 { return } - tokenPriviledges.Privileges[0].Attributes = 0x00000002 // SE_PRIVILEGE_ENABLED + tokenPrivileges.Privileges[0].Attributes = 0x00000002 // SE_PRIVILEGE_ENABLED procAdjustTokenPrivileges.Call( uintptr(token), 0, - uintptr(unsafe.Pointer(&tokenPriviledges)), - uintptr(unsafe.Sizeof(tokenPriviledges)), + uintptr(unsafe.Pointer(&tokenPrivileges)), + uintptr(unsafe.Sizeof(tokenPrivileges)), 0, 0) } @@ -435,15 +435,6 @@ func (p *Process) CwdWithContext(_ context.Context) (string, error) { return "", nil } -func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { - ppid, err := p.PpidWithContext(ctx) - if err != nil { - return nil, fmt.Errorf("could not get ParentProcessID: %s", err) - } - - return NewProcessWithContext(ctx, ppid) -} - func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { return []string{""}, common.ErrNotImplementedError } @@ -703,6 +694,9 @@ func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, er 0, true, windows.DUPLICATE_SAME_ACCESS) != nil { continue } + // release the new handle + defer windows.CloseHandle(windows.Handle(file)) + fileType, _ := windows.GetFileType(windows.Handle(file)) if fileType != windows.FILE_TYPE_DISK { continue diff --git a/process/process_windows_386.go b/process/process_windows_32bit.go similarity index 100% rename from process/process_windows_386.go rename to process/process_windows_32bit.go diff --git a/process/process_windows_amd64.go b/process/process_windows_64bit.go similarity index 100% rename from process/process_windows_amd64.go rename to process/process_windows_64bit.go diff --git a/process/testdata/darwin/ps-ax-opid_fail b/process/testdata/darwin/ps-ax-opid_fail deleted file mode 100644 index fce59ef..0000000 --- a/process/testdata/darwin/ps-ax-opid_fail +++ /dev/null @@ -1,10 +0,0 @@ - PID - 245 - 247 - 248 - 249 - 254 - 262 - 264 - 265 - 267