From ee12f66e4d2b3f9d8ca001c5f0d8a63b8fd035ee Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 16 Feb 2021 15:27:05 +0100 Subject: [PATCH] cpu, v3/cpu: use sysconf package instead of exec'ing getconf Currently, ClocksPerSec is determined by exec'ing getconf in func init, i.e. on startup of every program importing the package. getconf might not be present on some systems or is not executable by the current user. To avoid this hard to control dependency, use the github.com/tklauser/go-sysconf package which implements sysconf(3) entirely in Go without cgo. The package is supported on all platforms currently supported by the cpu and v3/cpu package of gopsutil. --- Gopkg.lock | 17 +++++++++++++++++ Gopkg.toml | 4 ++++ cpu/cpu_darwin.go | 13 +++---------- cpu/cpu_dragonfly.go | 13 +++---------- cpu/cpu_freebsd.go | 13 +++---------- cpu/cpu_linux.go | 13 +++---------- cpu/cpu_openbsd.go | 22 +++++++--------------- cpu/cpu_solaris.go | 13 ++++--------- v3/cpu/cpu_darwin.go | 13 +++---------- v3/cpu/cpu_dragonfly.go | 13 +++---------- v3/cpu/cpu_freebsd.go | 13 +++---------- v3/cpu/cpu_linux.go | 13 +++---------- v3/cpu/cpu_openbsd.go | 22 +++++++--------------- v3/cpu/cpu_solaris.go | 13 ++++--------- v3/go.mod | 3 ++- v3/go.sum | 9 +++++++-- 16 files changed, 76 insertions(+), 131 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index ca6cf37e8..6bae7891c 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -47,6 +47,22 @@ revision = "004e3cb72213e5e727e4e08f668ee6c8f27e5d32" version = "v1.6.0" +[[projects]] + digest = "1:935df8a10a215392af270f19b14ef39efd151d598cf96e4851e73ba678cdf290" + name = "github.com/tklauser/go-sysconf" + packages = ["."] + pruneopts = "UT" + revision = "6c733a705a84e0dfcaf092758e3cef627dc03034" + version = "v0.3.4" + +[[projects]] + digest = "1:e7bf47a37e6d0fb2f4bd0f65f574f8a92922f048cab3f106b0a7a413cbb14714" + name = "github.com/tklauser/numcpus" + packages = ["."] + pruneopts = "UT" + revision = "c03481b99a3f0b56b010e938559fddce19d3cf53" + version = "v0.1.0" + [[projects]] branch = "master" digest = "1:0afe79d034c63eea8c5977401f5fc135394751c1213ee6c991b0c6bec44f8f60" @@ -76,6 +92,7 @@ "github.com/StackExchange/wmi", "github.com/stretchr/testify/assert", "github.com/stretchr/testify/require", + "github.com/tklauser/go-sysconf", "golang.org/x/sys/unix", "golang.org/x/sys/windows", "golang.org/x/sys/windows/svc", diff --git a/Gopkg.toml b/Gopkg.toml index bf5784539..af7b47f2d 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -33,6 +33,10 @@ name = "github.com/stretchr/testify" version = "1.2.2" +[[constraint]] + name = "github.com/tklauser/go-sysconf" + version = "0.3.4" + [[constraint]] branch = "master" name = "golang.org/x/sys" diff --git a/cpu/cpu_darwin.go b/cpu/cpu_darwin.go index 3d3455ee6..421f1e16b 100644 --- a/cpu/cpu_darwin.go +++ b/cpu/cpu_darwin.go @@ -4,10 +4,10 @@ package cpu import ( "context" - "os/exec" "strconv" "strings" + "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) @@ -25,17 +25,10 @@ const ( var ClocksPerSec = float64(128) func init() { - getconf, err := exec.LookPath("getconf") - if err != nil { - return - } - out, err := invoke.Command(getconf, "CLK_TCK") + clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors if err == nil { - i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) - if err == nil { - ClocksPerSec = float64(i) - } + ClocksPerSec = float64(clkTck) } } diff --git a/cpu/cpu_dragonfly.go b/cpu/cpu_dragonfly.go index eed5beab7..45094df1d 100644 --- a/cpu/cpu_dragonfly.go +++ b/cpu/cpu_dragonfly.go @@ -3,7 +3,6 @@ package cpu import ( "context" "fmt" - "os/exec" "reflect" "regexp" "runtime" @@ -12,6 +11,7 @@ import ( "unsafe" "github.com/shirou/gopsutil/internal/common" + "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) @@ -25,17 +25,10 @@ var cpuTimesSize int var emptyTimes cpuTimes func init() { - getconf, err := exec.LookPath("getconf") - if err != nil { - return - } - out, err := invoke.Command(getconf, "CLK_TCK") + clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors if err == nil { - i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) - if err == nil { - ClocksPerSec = float64(i) - } + ClocksPerSec = float64(clkTck) } } diff --git a/cpu/cpu_freebsd.go b/cpu/cpu_freebsd.go index 57beffae1..24527af20 100644 --- a/cpu/cpu_freebsd.go +++ b/cpu/cpu_freebsd.go @@ -3,7 +3,6 @@ package cpu import ( "context" "fmt" - "os/exec" "reflect" "regexp" "runtime" @@ -12,6 +11,7 @@ import ( "unsafe" "github.com/shirou/gopsutil/internal/common" + "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) @@ -26,17 +26,10 @@ var cpuTimesSize int var emptyTimes cpuTimes func init() { - getconf, err := exec.LookPath("getconf") - if err != nil { - return - } - out, err := invoke.Command(getconf, "CLK_TCK") + clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors if err == nil { - i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) - if err == nil { - ClocksPerSec = float64(i) - } + ClocksPerSec = float64(clkTck) } } diff --git a/cpu/cpu_linux.go b/cpu/cpu_linux.go index f5adae706..b7040c7ea 100644 --- a/cpu/cpu_linux.go +++ b/cpu/cpu_linux.go @@ -6,28 +6,21 @@ import ( "context" "errors" "fmt" - "os/exec" "path/filepath" "strconv" "strings" "github.com/shirou/gopsutil/internal/common" + "github.com/tklauser/go-sysconf" ) var ClocksPerSec = float64(100) func init() { - getconf, err := exec.LookPath("getconf") - if err != nil { - return - } - out, err := invoke.CommandWithContext(context.Background(), getconf, "CLK_TCK") + clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors if err == nil { - i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) - if err == nil { - ClocksPerSec = i - } + ClocksPerSec = float64(clkTck) } } diff --git a/cpu/cpu_openbsd.go b/cpu/cpu_openbsd.go index b54cf9ca6..c761aa21d 100644 --- a/cpu/cpu_openbsd.go +++ b/cpu/cpu_openbsd.go @@ -7,13 +7,13 @@ import ( "context" "encoding/binary" "fmt" - "os/exec" "runtime" "strconv" "strings" "syscall" "github.com/shirou/gopsutil/internal/common" + "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) @@ -39,20 +39,12 @@ const ( var ClocksPerSec = float64(128) func init() { - func() { - getconf, err := exec.LookPath("getconf") - if err != nil { - return - } - out, err := invoke.Command(getconf, "CLK_TCK") - // ignore errors - if err == nil { - i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) - if err == nil { - ClocksPerSec = float64(i) - } - } - }() + clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) + // ignore errors + if err == nil { + ClocksPerSec = float64(clkTck) + } + func() { v, err := unix.Sysctl("kern.osrelease") // can't reuse host.PlatformInformation because of circular import if err != nil { diff --git a/cpu/cpu_solaris.go b/cpu/cpu_solaris.go index 3de098424..d97688d4a 100644 --- a/cpu/cpu_solaris.go +++ b/cpu/cpu_solaris.go @@ -10,22 +10,17 @@ import ( "sort" "strconv" "strings" + + "github.com/tklauser/go-sysconf" ) var ClocksPerSec = float64(128) func init() { - getconf, err := exec.LookPath("getconf") - if err != nil { - return - } - out, err := invoke.Command(getconf, "CLK_TCK") + clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors if err == nil { - i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) - if err == nil { - ClocksPerSec = float64(i) - } + ClocksPerSec = float64(clkTck) } } diff --git a/v3/cpu/cpu_darwin.go b/v3/cpu/cpu_darwin.go index 73151b40f..4c81e1bd8 100644 --- a/v3/cpu/cpu_darwin.go +++ b/v3/cpu/cpu_darwin.go @@ -4,10 +4,10 @@ package cpu import ( "context" - "os/exec" "strconv" "strings" + "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) @@ -25,17 +25,10 @@ const ( var ClocksPerSec = float64(128) func init() { - getconf, err := exec.LookPath("getconf") - if err != nil { - return - } - out, err := invoke.Command(getconf, "CLK_TCK") + clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors if err == nil { - i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) - if err == nil { - ClocksPerSec = float64(i) - } + ClocksPerSec = float64(clkTck) } } diff --git a/v3/cpu/cpu_dragonfly.go b/v3/cpu/cpu_dragonfly.go index ed6488933..a9c81cc5d 100644 --- a/v3/cpu/cpu_dragonfly.go +++ b/v3/cpu/cpu_dragonfly.go @@ -3,7 +3,6 @@ package cpu import ( "context" "fmt" - "os/exec" "reflect" "regexp" "runtime" @@ -12,6 +11,7 @@ import ( "unsafe" "github.com/shirou/gopsutil/v3/internal/common" + "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) @@ -25,17 +25,10 @@ var cpuTimesSize int var emptyTimes cpuTimes func init() { - getconf, err := exec.LookPath("getconf") - if err != nil { - return - } - out, err := invoke.Command(getconf, "CLK_TCK") + clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors if err == nil { - i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) - if err == nil { - ClocksPerSec = float64(i) - } + ClocksPerSec = float64(clkTck) } } diff --git a/v3/cpu/cpu_freebsd.go b/v3/cpu/cpu_freebsd.go index d0ec8345e..3b83cf315 100644 --- a/v3/cpu/cpu_freebsd.go +++ b/v3/cpu/cpu_freebsd.go @@ -3,7 +3,6 @@ package cpu import ( "context" "fmt" - "os/exec" "reflect" "regexp" "runtime" @@ -12,6 +11,7 @@ import ( "unsafe" "github.com/shirou/gopsutil/v3/internal/common" + "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) @@ -26,17 +26,10 @@ var cpuTimesSize int var emptyTimes cpuTimes func init() { - getconf, err := exec.LookPath("getconf") - if err != nil { - return - } - out, err := invoke.Command(getconf, "CLK_TCK") + clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors if err == nil { - i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) - if err == nil { - ClocksPerSec = float64(i) - } + ClocksPerSec = float64(clkTck) } } diff --git a/v3/cpu/cpu_linux.go b/v3/cpu/cpu_linux.go index c845aa2f8..fb0b72fa4 100644 --- a/v3/cpu/cpu_linux.go +++ b/v3/cpu/cpu_linux.go @@ -6,28 +6,21 @@ import ( "context" "errors" "fmt" - "os/exec" "path/filepath" "strconv" "strings" "github.com/shirou/gopsutil/v3/internal/common" + "github.com/tklauser/go-sysconf" ) var ClocksPerSec = float64(100) func init() { - getconf, err := exec.LookPath("getconf") - if err != nil { - return - } - out, err := invoke.CommandWithContext(context.Background(), getconf, "CLK_TCK") + clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors if err == nil { - i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) - if err == nil { - ClocksPerSec = i - } + ClocksPerSec = float64(clkTck) } } diff --git a/v3/cpu/cpu_openbsd.go b/v3/cpu/cpu_openbsd.go index cfe046740..8eb28db72 100644 --- a/v3/cpu/cpu_openbsd.go +++ b/v3/cpu/cpu_openbsd.go @@ -7,13 +7,13 @@ import ( "context" "encoding/binary" "fmt" - "os/exec" "runtime" "strconv" "strings" "syscall" "github.com/shirou/gopsutil/v3/internal/common" + "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) @@ -39,20 +39,12 @@ const ( var ClocksPerSec = float64(128) func init() { - func() { - getconf, err := exec.LookPath("getconf") - if err != nil { - return - } - out, err := invoke.Command(getconf, "CLK_TCK") - // ignore errors - if err == nil { - i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) - if err == nil { - ClocksPerSec = float64(i) - } - } - }() + clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) + // ignore errors + if err == nil { + ClocksPerSec = float64(clkTck) + } + func() { v, err := unix.Sysctl("kern.osrelease") // can't reuse host.PlatformInformation because of circular import if err != nil { diff --git a/v3/cpu/cpu_solaris.go b/v3/cpu/cpu_solaris.go index 3de098424..d97688d4a 100644 --- a/v3/cpu/cpu_solaris.go +++ b/v3/cpu/cpu_solaris.go @@ -10,22 +10,17 @@ import ( "sort" "strconv" "strings" + + "github.com/tklauser/go-sysconf" ) var ClocksPerSec = float64(128) func init() { - getconf, err := exec.LookPath("getconf") - if err != nil { - return - } - out, err := invoke.Command(getconf, "CLK_TCK") + clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors if err == nil { - i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) - if err == nil { - ClocksPerSec = float64(i) - } + ClocksPerSec = float64(clkTck) } } diff --git a/v3/go.mod b/v3/go.mod index 301154bd8..5a189dd70 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -6,5 +6,6 @@ require ( github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d github.com/go-ole/go-ole v1.2.4 // indirect github.com/stretchr/testify v1.6.1 - golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5 + github.com/tklauser/go-sysconf v0.3.4 + golang.org/x/sys v0.0.0-20210217105451-b926d437f341 ) diff --git a/v3/go.sum b/v3/go.sum index d4f32764e..792e78c05 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -9,8 +9,13 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5 h1:iCaAy5bMeEvwANu3YnJfWwI0kWAGkEa2RXPdweI/ysk= -golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= +github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= +github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= +github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= +golang.org/x/sys v0.0.0-20210217105451-b926d437f341 h1:2/QtM1mL37YmcsT8HaDNHDgTqqFVw+zr8UzMiBVLzYU= +golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=