diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..d207b1802 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.go text eol=lf diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c72429997..f31683027 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,11 +9,15 @@ permissions: jobs: golangci: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] permissions: contents: read # for actions/checkout to fetch code pull-requests: read # for golangci/golangci-lint-action to fetch pull requests name: lint - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} steps: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 diff --git a/cpu/cpu_windows.go b/cpu/cpu_windows.go index 4476b91cb..a71df97fe 100644 --- a/cpu/cpu_windows.go +++ b/cpu/cpu_windows.go @@ -6,11 +6,13 @@ package cpu import ( "context" "fmt" + "strconv" "unsafe" - "github.com/shirou/gopsutil/v4/internal/common" "github.com/yusufpapurcu/wmi" "golang.org/x/sys/windows" + + "github.com/shirou/gopsutil/v4/internal/common" ) var procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo") @@ -110,7 +112,7 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) { cpu := InfoStat{ CPU: int32(i), - Family: fmt.Sprintf("%d", l.Family), + Family: strconv.FormatUint(uint64(l.Family), 10), VendorID: l.Manufacturer, ModelName: l.Name, Cores: int32(l.NumberOfLogicalProcessors), diff --git a/disk/disk_darwin.go b/disk/disk_darwin.go index f5482ed2b..94f10b9fb 100644 --- a/disk/disk_darwin.go +++ b/disk/disk_darwin.go @@ -222,7 +222,7 @@ func (i *ioCounters) getDriveStat(d uint32) (*IOCountersStat, error) { defer i.ioObjectRelease(parent) if !ioObjectConformsTo(parent, "IOBlockStorageDriver") { - //return nil, fmt.Errorf("ERROR: the object is not of the IOBlockStorageDriver class") + // return nil, fmt.Errorf("ERROR: the object is not of the IOBlockStorageDriver class") return nil, nil } diff --git a/disk/disk_windows.go b/disk/disk_windows.go index 4f371a332..5f2438941 100644 --- a/disk/disk_windows.go +++ b/disk/disk_windows.go @@ -6,13 +6,14 @@ package disk import ( "bytes" "context" - "fmt" + "errors" "syscall" "unsafe" - "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/windows" "golang.org/x/sys/windows/registry" + + "github.com/shirou/gopsutil/v4/internal/common" ) var ( @@ -202,11 +203,11 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC if typeret != windows.DRIVE_FIXED { continue } - szDevice := fmt.Sprintf(`\\.\%s`, path) + szDevice := `\\.\` + path const IOCTL_DISK_PERFORMANCE = 0x70020 h, err := windows.CreateFile(syscall.StringToUTF16Ptr(szDevice), 0, windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE, nil, windows.OPEN_EXISTING, 0, 0) if err != nil { - if err == windows.ERROR_FILE_NOT_FOUND { + if errors.Is(err, windows.ERROR_FILE_NOT_FOUND) { continue } return drivemap, err diff --git a/host/host_windows.go b/host/host_windows.go index 99a23bd2b..41f4b7f02 100644 --- a/host/host_windows.go +++ b/host/host_windows.go @@ -13,9 +13,10 @@ import ( "time" "unsafe" + "golang.org/x/sys/windows" + "github.com/shirou/gopsutil/v4/internal/common" "github.com/shirou/gopsutil/v4/process" - "golang.org/x/sys/windows" ) var ( @@ -79,7 +80,7 @@ func HostIDWithContext(ctx context.Context) (string, error) { hostID := windows.UTF16ToString(regBuf[:]) hostIDLen := len(hostID) if hostIDLen != uuidLen { - return "", fmt.Errorf("HostID incorrect: %q\n", hostID) + return "", fmt.Errorf("HostID incorrect: %q\n", hostID) //nolint:revive //FIXME } return strings.ToLower(hostID), nil @@ -135,15 +136,15 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) { return t, nil } -func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) { - platform, family, _, displayVersion, err := platformInformation(ctx) +func PlatformInformationWithContext(_ context.Context) (platform string, family string, version string, err error) { + platform, family, _, displayVersion, err := platformInformation() if err != nil { return "", "", "", err } return platform, family, displayVersion, nil } -func platformInformation(ctx context.Context) (platform, family, version, displayVersion string, err error) { +func platformInformation() (platform, family, version, displayVersion string, err error) { // GetVersionEx lies on Windows 8.1 and returns as Windows 8 if we don't declare compatibility in manifest // RtlGetVersion bypasses this lying layer and returns the true Windows version // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-rtlgetversion @@ -152,26 +153,26 @@ func platformInformation(ctx context.Context) (platform, family, version, displa osInfo.dwOSVersionInfoSize = uint32(unsafe.Sizeof(osInfo)) ret, _, err := procRtlGetVersion.Call(uintptr(unsafe.Pointer(&osInfo))) if ret != 0 { - return + return //nolint:nakedret //FIXME } // Platform var h windows.Handle // like HostIDWithContext(), we query the registry using the raw windows.RegOpenKeyEx/RegQueryValueEx err = windows.RegOpenKeyEx(windows.HKEY_LOCAL_MACHINE, windows.StringToUTF16Ptr(`SOFTWARE\Microsoft\Windows NT\CurrentVersion`), 0, windows.KEY_READ|windows.KEY_WOW64_64KEY, &h) if err != nil { - return + return //nolint:nakedret //FIXME } defer windows.RegCloseKey(h) var bufLen uint32 var valType uint32 err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`ProductName`), nil, &valType, nil, &bufLen) if err != nil { - return + return //nolint:nakedret //FIXME } regBuf := make([]uint16, bufLen/2+1) err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`ProductName`), nil, &valType, (*byte)(unsafe.Pointer(®Buf[0])), &bufLen) if err != nil { - return + return //nolint:nakedret //FIXME } platform = windows.UTF16ToString(regBuf[:]) if strings.Contains(platform, "Windows 10") { // check build number to determine whether it's actually Windows 11 @@ -243,8 +244,8 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { return "", "", common.ErrNotImplementedError } -func KernelVersionWithContext(ctx context.Context) (string, error) { - _, _, version, _, err := platformInformation(ctx) +func KernelVersionWithContext(_ context.Context) (string, error) { + _, _, version, _, err := platformInformation() return version, err } diff --git a/internal/common/common_darwin.go b/internal/common/common_darwin.go index 2de3bb145..afa780d34 100644 --- a/internal/common/common_darwin.go +++ b/internal/common/common_darwin.go @@ -5,6 +5,7 @@ package common import ( "context" + "errors" "fmt" "os" "os/exec" @@ -306,7 +307,7 @@ const ( func NewSMC(ioKit *Library) (*SMC, error) { if ioKit.path != IOKit { - return nil, fmt.Errorf("library is not IOKit") + return nil, errors.New("library is not IOKit") } ioServiceGetMatchingService := GetFunc[IOServiceGetMatchingServiceFunc](ioKit, IOServiceGetMatchingServiceSym) @@ -324,7 +325,7 @@ func NewSMC(ioKit *Library) (*SMC, error) { var conn uint32 if result := ioServiceOpen(service, machTaskSelf(), 0, &conn); result != 0 { - return nil, fmt.Errorf("ERROR: IOServiceOpen failed") + return nil, errors.New("ERROR: IOServiceOpen failed") } ioObjectRelease(service) @@ -343,7 +344,7 @@ func (s *SMC) Close() error { ioServiceClose := GetFunc[IOServiceCloseFunc](s.lib, IOServiceCloseSym) if result := ioServiceClose(s.conn); result != 0 { - return fmt.Errorf("ERROR: IOServiceClose failed") + return errors.New("ERROR: IOServiceClose failed") } return nil } @@ -367,8 +368,8 @@ func (s CStr) Ptr() *byte { return &s[0] } -func (c CStr) Addr() uintptr { - return uintptr(unsafe.Pointer(c.Ptr())) +func (s CStr) Addr() uintptr { + return uintptr(unsafe.Pointer(s.Ptr())) } func (s CStr) GoString() string { diff --git a/internal/common/common_windows.go b/internal/common/common_windows.go index 766ed2fcb..e7e82202b 100644 --- a/internal/common/common_windows.go +++ b/internal/common/common_windows.go @@ -273,19 +273,19 @@ type SystemExtendedHandleInformation struct { // CallWithExpandingBuffer https://github.com/hillu/go-ntdll func CallWithExpandingBuffer(fn func() NtStatus, buf *[]byte, resultLength *uint32) NtStatus { for { - if st := fn(); st == STATUS_BUFFER_OVERFLOW || st == STATUS_BUFFER_TOO_SMALL || st == STATUS_INFO_LENGTH_MISMATCH { + st := fn() + if st == STATUS_BUFFER_OVERFLOW || st == STATUS_BUFFER_TOO_SMALL || st == STATUS_INFO_LENGTH_MISMATCH { if int(*resultLength) <= cap(*buf) { (*reflect.SliceHeader)(unsafe.Pointer(buf)).Len = int(*resultLength) } else { *buf = make([]byte, int(*resultLength)) } continue - } else { - if !st.IsError() { - *buf = (*buf)[:int(*resultLength)] - } - return st } + if !st.IsError() { + *buf = (*buf)[:int(*resultLength)] + } + return st } } diff --git a/load/load_windows.go b/load/load_windows.go index a55c7b40a..f430d2aa7 100644 --- a/load/load_windows.go +++ b/load/load_windows.go @@ -14,9 +14,9 @@ import ( var ( loadErr error - loadAvg1M float64 = 0.0 - loadAvg5M float64 = 0.0 - loadAvg15M float64 = 0.0 + loadAvg1M = 0.0 + loadAvg5M = 0.0 + loadAvg15M = 0.0 loadAvgMutex sync.RWMutex loadAvgGoroutineOnce sync.Once ) @@ -27,10 +27,10 @@ var ( // code https://github.com/giampaolo/psutil/blob/8415355c8badc9c94418b19bdf26e622f06f0cce/psutil/arch/windows/wmi.c func loadAvgGoroutine(ctx context.Context) { var ( - samplingFrequency time.Duration = 5 * time.Second - loadAvgFactor1M float64 = 1 / math.Exp(samplingFrequency.Seconds()/time.Minute.Seconds()) - loadAvgFactor5M float64 = 1 / math.Exp(samplingFrequency.Seconds()/(5*time.Minute).Seconds()) - loadAvgFactor15M float64 = 1 / math.Exp(samplingFrequency.Seconds()/(15*time.Minute).Seconds()) + samplingFrequency = 5 * time.Second + loadAvgFactor1M = 1 / math.Exp(samplingFrequency.Seconds()/time.Minute.Seconds()) + loadAvgFactor5M = 1 / math.Exp(samplingFrequency.Seconds()/(5*time.Minute).Seconds()) + loadAvgFactor15M = 1 / math.Exp(samplingFrequency.Seconds()/(15*time.Minute).Seconds()) currentLoad float64 ) diff --git a/mem/mem_darwin_test.go b/mem/mem_darwin_test.go index c7f5668bd..c2a6f3ff4 100644 --- a/mem/mem_darwin_test.go +++ b/mem/mem_darwin_test.go @@ -9,39 +9,40 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestVirtualMemoryDarwin(t *testing.T) { v, err := VirtualMemory() - assert.Nil(t, err) + require.NoError(t, err) outBytes, err := invoke.Command("/usr/sbin/sysctl", "hw.memsize") - assert.Nil(t, err) + require.NoError(t, err) outString := string(outBytes) outString = strings.TrimSpace(outString) outParts := strings.Split(outString, " ") actualTotal, err := strconv.ParseInt(outParts[1], 10, 64) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, uint64(actualTotal), v.Total) - assert.True(t, v.Available > 0) + assert.Positive(t, v.Available) assert.Equal(t, v.Available, v.Free+v.Inactive, "%v", v) - assert.True(t, v.Used > 0) - assert.True(t, v.Used < v.Total) + assert.Positive(t, v.Used) + assert.Less(t, v.Used, v.Total) - assert.True(t, v.UsedPercent > 0) - assert.True(t, v.UsedPercent < 100) + assert.Positive(t, v.UsedPercent) + assert.Less(t, v.UsedPercent, 100.0) - assert.True(t, v.Free > 0) - assert.True(t, v.Free < v.Available) + assert.Positive(t, v.Free) + assert.Less(t, v.Free, v.Available) - assert.True(t, v.Active > 0) - assert.True(t, v.Active < v.Total) + assert.Positive(t, v.Active) + assert.Less(t, v.Active, v.Total) - assert.True(t, v.Inactive > 0) - assert.True(t, v.Inactive < v.Total) + assert.Positive(t, v.Inactive) + assert.Less(t, v.Inactive, v.Total) - assert.True(t, v.Wired > 0) - assert.True(t, v.Wired < v.Total) + assert.Positive(t, v.Wired) + assert.Less(t, v.Wired, v.Total) } diff --git a/mem/mem_windows.go b/mem/mem_windows.go index a94b61f4b..d7dcef4d7 100644 --- a/mem/mem_windows.go +++ b/mem/mem_windows.go @@ -9,8 +9,9 @@ import ( "syscall" "unsafe" - "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/windows" + + "github.com/shirou/gopsutil/v4/internal/common" ) var ( diff --git a/net/net_darwin.go b/net/net_darwin.go index 86c541e93..f640931f2 100644 --- a/net/net_darwin.go +++ b/net/net_darwin.go @@ -30,14 +30,14 @@ func parseNetstatLine(line string) (stat *IOCountersStat, linkID *uint, err erro if columns[0] == "Name" { err = errNetstatHeader - return + return //nolint:nakedret //FIXME } // try to extract the numeric value from if subMatch := netstatLinkRegexp.FindStringSubmatch(columns[2]); len(subMatch) == 2 { numericValue, err = strconv.ParseUint(subMatch[1], 10, 64) if err != nil { - return + return //nolint:nakedret //FIXME } linkIDUint := uint(numericValue) linkID = &linkIDUint @@ -51,7 +51,7 @@ func parseNetstatLine(line string) (stat *IOCountersStat, linkID *uint, err erro } if numberColumns < 11 || numberColumns > 13 { err = fmt.Errorf("Line %q do have an invalid number of columns %d", line, numberColumns) - return + return //nolint:nakedret //FIXME } parsed := make([]uint64, 0, 7) @@ -74,7 +74,7 @@ func parseNetstatLine(line string) (stat *IOCountersStat, linkID *uint, err erro } if numericValue, err = strconv.ParseUint(target, 10, 64); err != nil { - return + return //nolint:nakedret //FIXME } parsed = append(parsed, numericValue) } @@ -91,7 +91,7 @@ func parseNetstatLine(line string) (stat *IOCountersStat, linkID *uint, err erro if len(parsed) == 7 { stat.Dropout = parsed[6] } - return + return //nolint:nakedret //FIXME } type netstatInterface struct { diff --git a/net/net_darwin_test.go b/net/net_darwin_test.go index 86ed1262d..ba4131e80 100644 --- a/net/net_darwin_test.go +++ b/net/net_darwin_test.go @@ -137,5 +137,5 @@ func TestParseNetstatTruncated(t *testing.T) { mapUsage := newMapInterfaceNameUsage(nsInterfaces) assert.True(t, mapUsage.isTruncated()) - assert.Equal(t, 3, len(mapUsage.notTruncated()), "en0, gif0 and stf0") + assert.Len(t, mapUsage.notTruncated(), 3, "en0, gif0 and stf0") } diff --git a/net/net_windows.go b/net/net_windows.go index 00ebf89ef..1dff373cd 100644 --- a/net/net_windows.go +++ b/net/net_windows.go @@ -5,14 +5,16 @@ package net import ( "context" + "errors" "fmt" "net" "os" "syscall" "unsafe" - "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/windows" + + "github.com/shirou/gopsutil/v4/internal/common" ) var ( @@ -197,7 +199,7 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, } func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) { - return IOCounters(pernic) + return IOCounters(pernic) //nolint:contextcheck //FIXME } func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { @@ -238,7 +240,7 @@ func getProcInet(kinds []netConnectionKindType, pid int32) ([]ConnectionStat, er func getNetStatWithKind(kindType netConnectionKindType) ([]ConnectionStat, error) { if kindType.filename == "" { - return nil, fmt.Errorf("kind filename must be required") + return nil, errors.New("kind filename must be required") } switch kindType.filename { @@ -360,7 +362,7 @@ func getTCPConnections(family uint32) ([]ConnectionStat, error) { ) if family == 0 { - return nil, fmt.Errorf("faimly must be required") + return nil, errors.New("faimly must be required") } for { @@ -390,7 +392,7 @@ func getTCPConnections(family uint32) ([]ConnectionStat, error) { if err == nil { break } - if err != windows.ERROR_INSUFFICIENT_BUFFER { + if !errors.Is(err, windows.ERROR_INSUFFICIENT_BUFFER) { return nil, err } buf = make([]byte, size) @@ -441,7 +443,7 @@ func getUDPConnections(family uint32) ([]ConnectionStat, error) { ) if family == 0 { - return nil, fmt.Errorf("faimly must be required") + return nil, errors.New("faimly must be required") } for { @@ -473,7 +475,7 @@ func getUDPConnections(family uint32) ([]ConnectionStat, error) { if err == nil { break } - if err != windows.ERROR_INSUFFICIENT_BUFFER { + if !errors.Is(err, windows.ERROR_INSUFFICIENT_BUFFER) { return nil, err } buf = make([]byte, size) diff --git a/process/process_darwin.go b/process/process_darwin.go index 33abc10ac..2c14f2e09 100644 --- a/process/process_darwin.go +++ b/process/process_darwin.go @@ -7,6 +7,7 @@ import ( "bytes" "context" "encoding/binary" + "errors" "fmt" "path/filepath" "runtime" @@ -348,7 +349,7 @@ func (p *Process) CwdWithContext(ctx context.Context) (string, error) { ret := procPidInfo(p.Pid, common.PROC_PIDVNODEPATHINFO, 0, uintptr(unsafe.Pointer(&vpi)), vpiSize) errno, _ := lib.Dlsym("errno") err = *(**unix.Errno)(unsafe.Pointer(&errno)) - if err == unix.EPERM { + if errors.Is(err, unix.EPERM) { return "", ErrorNotPermitted } @@ -373,11 +374,11 @@ func procArgs(pid int32) ([]byte, int, error) { return procargs, int(binary.LittleEndian.Uint32(nargs)), nil } -func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { - return p.cmdlineSliceWithContext(ctx, true) +func (p *Process) CmdlineSliceWithContext(_ context.Context) ([]string, error) { + return p.cmdlineSlice() } -func (p *Process) cmdlineSliceWithContext(ctx context.Context, fallback bool) ([]string, error) { +func (p *Process) cmdlineSlice() ([]string, error) { pargs, nargs, err := procArgs(p.Pid) if err != nil { return nil, err @@ -408,8 +409,8 @@ func (p *Process) cmdlineSliceWithContext(ctx context.Context, fallback bool) ([ } // 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) +func (p *Process) cmdNameWithContext(_ context.Context) (string, error) { + r, err := p.cmdlineSlice() if err != nil { return "", err } diff --git a/process/process_windows.go b/process/process_windows.go index 012886d6c..00b223627 100644 --- a/process/process_windows.go +++ b/process/process_windows.go @@ -18,10 +18,11 @@ import ( "unicode/utf16" "unsafe" + "golang.org/x/sys/windows" + "github.com/shirou/gopsutil/v4/cpu" "github.com/shirou/gopsutil/v4/internal/common" "github.com/shirou/gopsutil/v4/net" - "golang.org/x/sys/windows" ) type Signal = syscall.Signal @@ -245,7 +246,7 @@ func pidsWithContext(ctx context.Context) ([]int32, error) { // inspired by https://gist.github.com/henkman/3083408 // and https://github.com/giampaolo/psutil/blob/1c3a15f637521ba5c0031283da39c733fda53e4c/psutil/arch/windows/process_info.c#L315-L329 var ret []int32 - var read uint32 = 0 + var read uint32 var psSize uint32 = 1024 const dwordSize uint32 = 4 @@ -288,10 +289,10 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) { return false, err } h, err := windows.OpenProcess(windows.SYNCHRONIZE, false, uint32(pid)) - if err == windows.ERROR_ACCESS_DENIED { + if errors.Is(err, windows.ERROR_ACCESS_DENIED) { return true, nil } - if err == windows.ERROR_INVALID_PARAMETER { + if errors.Is(err, windows.ERROR_INVALID_PARAMETER) { return false, nil } if err != nil { @@ -330,7 +331,7 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { exe, err := p.ExeWithContext(ctx) if err != nil { - return "", fmt.Errorf("could not get Name: %s", err) + return "", fmt.Errorf("could not get Name: %w", err) } return filepath.Base(exe), nil @@ -370,7 +371,7 @@ func (p *Process) ExeWithContext(ctx context.Context) (string, error) { func (p *Process) CmdlineWithContext(_ context.Context) (string, error) { cmdline, err := getProcessCommandLine(p.Pid) if err != nil { - return "", fmt.Errorf("could not get CommandLine: %s", err) + return "", fmt.Errorf("could not get CommandLine: %w", err) } return cmdline, nil } @@ -386,7 +387,7 @@ func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { ru, err := getRusage(p.Pid) if err != nil { - return 0, fmt.Errorf("could not get CreationDate: %s", err) + return 0, fmt.Errorf("could not get CreationDate: %w", err) } return ru.CreationTime.Nanoseconds() / 1000000, nil @@ -394,7 +395,7 @@ func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { func (p *Process) CwdWithContext(_ context.Context) (string, error) { h, err := windows.OpenProcess(processQueryInformation|windows.PROCESS_VM_READ, false, uint32(p.Pid)) - if err == windows.ERROR_ACCESS_DENIED || err == windows.ERROR_INVALID_PARAMETER { + if errors.Is(err, windows.ERROR_ACCESS_DENIED) || errors.Is(err, windows.ERROR_INVALID_PARAMETER) { return "", nil } if err != nil { @@ -822,9 +823,9 @@ func (p *Process) KillWithContext(ctx context.Context) error { } func (p *Process) EnvironWithContext(ctx context.Context) ([]string, error) { - envVars, err := getProcessEnvironmentVariables(p.Pid, ctx) + envVars, err := getProcessEnvironmentVariables(ctx, p.Pid) if err != nil { - return nil, fmt.Errorf("could not get environment variables: %s", err) + return nil, fmt.Errorf("could not get environment variables: %w", err) } return envVars, nil } @@ -844,7 +845,7 @@ func (p *Process) setPpid(ppid int32) { p.parent = ppid } -func getFromSnapProcess(pid int32) (int32, int32, string, error) { +func getFromSnapProcess(pid int32) (int32, int32, string, error) { //nolint:unparam //FIXME snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, uint32(pid)) if err != nil { return 0, 0, "", err @@ -872,7 +873,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) { pids, err := PidsWithContext(ctx) if err != nil { - return out, fmt.Errorf("could not get Processes %s", err) + return out, fmt.Errorf("could not get Processes %w", err) } for _, pid := range pids { @@ -963,13 +964,13 @@ func getUserProcessParams32(handle windows.Handle) (rtlUserProcessParameters32, buf := readProcessMemory(syscall.Handle(handle), true, pebAddress, uint(unsafe.Sizeof(processEnvironmentBlock32{}))) if len(buf) != int(unsafe.Sizeof(processEnvironmentBlock32{})) { - return rtlUserProcessParameters32{}, fmt.Errorf("cannot read process PEB") + return rtlUserProcessParameters32{}, errors.New("cannot read process PEB") } peb := (*processEnvironmentBlock32)(unsafe.Pointer(&buf[0])) userProcessAddress := uint64(peb.ProcessParameters) buf = readProcessMemory(syscall.Handle(handle), true, userProcessAddress, uint(unsafe.Sizeof(rtlUserProcessParameters32{}))) if len(buf) != int(unsafe.Sizeof(rtlUserProcessParameters32{})) { - return rtlUserProcessParameters32{}, fmt.Errorf("cannot read user process parameters") + return rtlUserProcessParameters32{}, errors.New("cannot read user process parameters") } return *(*rtlUserProcessParameters32)(unsafe.Pointer(&buf[0])), nil } @@ -982,13 +983,13 @@ func getUserProcessParams64(handle windows.Handle) (rtlUserProcessParameters64, buf := readProcessMemory(syscall.Handle(handle), false, pebAddress, uint(unsafe.Sizeof(processEnvironmentBlock64{}))) if len(buf) != int(unsafe.Sizeof(processEnvironmentBlock64{})) { - return rtlUserProcessParameters64{}, fmt.Errorf("cannot read process PEB") + return rtlUserProcessParameters64{}, errors.New("cannot read process PEB") } peb := (*processEnvironmentBlock64)(unsafe.Pointer(&buf[0])) userProcessAddress := peb.ProcessParameters buf = readProcessMemory(syscall.Handle(handle), false, userProcessAddress, uint(unsafe.Sizeof(rtlUserProcessParameters64{}))) if len(buf) != int(unsafe.Sizeof(rtlUserProcessParameters64{})) { - return rtlUserProcessParameters64{}, fmt.Errorf("cannot read user process parameters") + return rtlUserProcessParameters64{}, errors.New("cannot read user process parameters") } return *(*rtlUserProcessParameters64)(unsafe.Pointer(&buf[0])), nil } @@ -1038,9 +1039,9 @@ func is32BitProcess(h windows.Handle) bool { return procIs32Bits } -func getProcessEnvironmentVariables(pid int32, ctx context.Context) ([]string, error) { +func getProcessEnvironmentVariables(ctx context.Context, pid int32) ([]string, error) { h, err := windows.OpenProcess(processQueryInformation|windows.PROCESS_VM_READ, false, uint32(pid)) - if err == windows.ERROR_ACCESS_DENIED || err == windows.ERROR_INVALID_PARAMETER { + if errors.Is(err, windows.ERROR_ACCESS_DENIED) || errors.Is(err, windows.ERROR_INVALID_PARAMETER) { return nil, nil } if err != nil { @@ -1124,7 +1125,7 @@ func (p *processReader) Read(buf []byte) (int, error) { func getProcessCommandLine(pid int32) (string, error) { h, err := windows.OpenProcess(processQueryInformation|windows.PROCESS_VM_READ, false, uint32(pid)) - if err == windows.ERROR_ACCESS_DENIED || err == windows.ERROR_INVALID_PARAMETER { + if errors.Is(err, windows.ERROR_ACCESS_DENIED) || errors.Is(err, windows.ERROR_INVALID_PARAMETER) { return "", nil } if err != nil { diff --git a/process/process_windows_64bit.go b/process/process_windows_64bit.go index befe52139..69018fefd 100644 --- a/process/process_windows_64bit.go +++ b/process/process_windows_64bit.go @@ -7,8 +7,9 @@ import ( "syscall" "unsafe" - "github.com/shirou/gopsutil/v4/internal/common" "golang.org/x/sys/windows" + + "github.com/shirou/gopsutil/v4/internal/common" ) type PROCESS_MEMORY_COUNTERS struct { @@ -38,26 +39,23 @@ func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) (uint64, er ) if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS { return uint64(wow64), nil - } else { - return 0, windows.NTStatus(ret) } - } else { - // we are on a 64-bit process reading an external 64-bit process - var info processBasicInformation64 + return 0, windows.NTStatus(ret) + } + // we are on a 64-bit process reading an external 64-bit process + var info processBasicInformation64 - ret, _, _ := common.ProcNtQueryInformationProcess.Call( - uintptr(procHandle), - uintptr(common.ProcessBasicInformation), - uintptr(unsafe.Pointer(&info)), - uintptr(unsafe.Sizeof(info)), - uintptr(0), - ) - if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS { - return info.PebBaseAddress, nil - } else { - return 0, windows.NTStatus(ret) - } + ret, _, _ := common.ProcNtQueryInformationProcess.Call( + uintptr(procHandle), + uintptr(common.ProcessBasicInformation), + uintptr(unsafe.Pointer(&info)), + uintptr(unsafe.Sizeof(info)), + uintptr(0), + ) + if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS { + return info.PebBaseAddress, nil } + return 0, windows.NTStatus(ret) } func readProcessMemory(procHandle syscall.Handle, _ bool, address uint64, size uint) []byte { diff --git a/sensors/sensors_windows.go b/sensors/sensors_windows.go index 32b9ee492..aa1e42b3c 100644 --- a/sensors/sensors_windows.go +++ b/sensors/sensors_windows.go @@ -7,8 +7,9 @@ import ( "context" "math" - "github.com/shirou/gopsutil/v4/internal/common" "github.com/yusufpapurcu/wmi" + + "github.com/shirou/gopsutil/v4/internal/common" ) type msAcpi_ThermalZoneTemperature struct { diff --git a/winservices/winservices.go b/winservices/winservices.go index 0c85a0179..1c062652d 100644 --- a/winservices/winservices.go +++ b/winservices/winservices.go @@ -5,6 +5,7 @@ package winservices import ( "context" + "errors" "unsafe" "golang.org/x/sys/windows" @@ -86,7 +87,7 @@ func (s *Service) QueryStatusWithContext(ctx context.Context) (ServiceStatus, er var bytesNeeded uint32 var buf []byte - if err := windows.QueryServiceStatusEx(s.srv.Handle, windows.SC_STATUS_PROCESS_INFO, nil, 0, &bytesNeeded); err != windows.ERROR_INSUFFICIENT_BUFFER { + if err := windows.QueryServiceStatusEx(s.srv.Handle, windows.SC_STATUS_PROCESS_INFO, nil, 0, &bytesNeeded); !errors.Is(err, windows.ERROR_INSUFFICIENT_BUFFER) { return ServiceStatus{}, err }