1
2
3 package common
4
5 import (
6 "fmt"
7 "os"
8 "os/exec"
9 "strings"
10 "unsafe"
11
12 "golang.org/x/sys/unix"
13 )
14
15 func SysctlUint(mib string) (uint64, error) {
16 buf, err := unix.SysctlRaw(mib)
17 if err != nil {
18 return 0, err
19 }
20 if len(buf) == 8 {
21 return *(*uint64)(unsafe.Pointer(&buf[0])), nil
22 }
23 if len(buf) == 4 {
24 t := *(*uint32)(unsafe.Pointer(&buf[0]))
25 return uint64(t), nil
26 }
27 return 0, fmt.Errorf("unexpected size: %s, %d", mib, len(buf))
28 }
29
30 func DoSysctrl(mib string) ([]string, error) {
31 sysctl, err := exec.LookPath("sysctl")
32 if err != nil {
33 return []string{}, err
34 }
35 cmd := exec.Command(sysctl, "-n", mib)
36 cmd.Env = getSysctrlEnv(os.Environ())
37 out, err := cmd.Output()
38 if err != nil {
39 return []string{}, err
40 }
41 v := strings.Replace(string(out), "{ ", "", 1)
42 v = strings.Replace(string(v), " }", "", 1)
43 values := strings.Fields(string(v))
44
45 return values, nil
46 }
47
48 func CallSyscall(mib []int32) ([]byte, uint64, error) {
49 mibptr := unsafe.Pointer(&mib[0])
50 miblen := uint64(len(mib))
51
52
53 length := uint64(0)
54 _, _, err := unix.Syscall6(
55 unix.SYS___SYSCTL,
56 uintptr(mibptr),
57 uintptr(miblen),
58 0,
59 uintptr(unsafe.Pointer(&length)),
60 0,
61 0)
62 if err != 0 {
63 var b []byte
64 return b, length, err
65 }
66 if length == 0 {
67 var b []byte
68 return b, length, err
69 }
70
71 buf := make([]byte, length)
72 _, _, err = unix.Syscall6(
73 unix.SYS___SYSCTL,
74 uintptr(mibptr),
75 uintptr(miblen),
76 uintptr(unsafe.Pointer(&buf[0])),
77 uintptr(unsafe.Pointer(&length)),
78 0,
79 0)
80 if err != 0 {
81 return buf, length, err
82 }
83
84 return buf, length, nil
85 }
86
View as plain text