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