host_freebsd.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // +build freebsd
  2. package host
  3. import (
  4. "bytes"
  5. "context"
  6. "encoding/binary"
  7. "io/ioutil"
  8. "math"
  9. "os"
  10. "strings"
  11. "unsafe"
  12. "github.com/shirou/gopsutil/internal/common"
  13. "github.com/shirou/gopsutil/process"
  14. "golang.org/x/sys/unix"
  15. )
  16. const (
  17. UTNameSize = 16 /* see MAXLOGNAME in <sys/param.h> */
  18. UTLineSize = 8
  19. UTHostSize = 16
  20. )
  21. func HostIDWithContext(ctx context.Context) (string, error) {
  22. uuid, err := unix.Sysctl("kern.hostuuid")
  23. if err != nil {
  24. return "", err
  25. }
  26. return strings.ToLower(uuid), err
  27. }
  28. func numProcs(ctx context.Context) (uint64, error) {
  29. procs, err := process.PidsWithContext(ctx)
  30. if err != nil {
  31. return 0, err
  32. }
  33. return uint64(len(procs)), nil
  34. }
  35. func UsersWithContext(ctx context.Context) ([]UserStat, error) {
  36. utmpfile := "/var/run/utx.active"
  37. if !common.PathExists(utmpfile) {
  38. utmpfile = "/var/run/utmp" // before 9.0
  39. return getUsersFromUtmp(utmpfile)
  40. }
  41. var ret []UserStat
  42. file, err := os.Open(utmpfile)
  43. if err != nil {
  44. return ret, err
  45. }
  46. defer file.Close()
  47. buf, err := ioutil.ReadAll(file)
  48. if err != nil {
  49. return ret, err
  50. }
  51. entrySize := sizeOfUtmpx
  52. count := len(buf) / entrySize
  53. for i := 0; i < count; i++ {
  54. b := buf[i*sizeOfUtmpx : (i+1)*sizeOfUtmpx]
  55. var u Utmpx
  56. br := bytes.NewReader(b)
  57. err := binary.Read(br, binary.BigEndian, &u)
  58. if err != nil || u.Type != 4 {
  59. continue
  60. }
  61. sec := math.Floor(float64(u.Tv) / 1000000)
  62. user := UserStat{
  63. User: common.IntToString(u.User[:]),
  64. Terminal: common.IntToString(u.Line[:]),
  65. Host: common.IntToString(u.Host[:]),
  66. Started: int(sec),
  67. }
  68. ret = append(ret, user)
  69. }
  70. return ret, nil
  71. }
  72. func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
  73. platform, err := unix.Sysctl("kern.ostype")
  74. if err != nil {
  75. return "", "", "", err
  76. }
  77. version, err := unix.Sysctl("kern.osrelease")
  78. if err != nil {
  79. return "", "", "", err
  80. }
  81. return strings.ToLower(platform), "", strings.ToLower(version), nil
  82. }
  83. func VirtualizationWithContext(ctx context.Context) (string, string, error) {
  84. return "", "", common.ErrNotImplementedError
  85. }
  86. // before 9.0
  87. func getUsersFromUtmp(utmpfile string) ([]UserStat, error) {
  88. var ret []UserStat
  89. file, err := os.Open(utmpfile)
  90. if err != nil {
  91. return ret, err
  92. }
  93. defer file.Close()
  94. buf, err := ioutil.ReadAll(file)
  95. if err != nil {
  96. return ret, err
  97. }
  98. u := Utmp{}
  99. entrySize := int(unsafe.Sizeof(u))
  100. count := len(buf) / entrySize
  101. for i := 0; i < count; i++ {
  102. b := buf[i*entrySize : i*entrySize+entrySize]
  103. var u Utmp
  104. br := bytes.NewReader(b)
  105. err := binary.Read(br, binary.LittleEndian, &u)
  106. if err != nil || u.Time == 0 {
  107. continue
  108. }
  109. user := UserStat{
  110. User: common.IntToString(u.Name[:]),
  111. Terminal: common.IntToString(u.Line[:]),
  112. Host: common.IntToString(u.Host[:]),
  113. Started: int(u.Time),
  114. }
  115. ret = append(ret, user)
  116. }
  117. return ret, nil
  118. }
  119. func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
  120. return []TemperatureStat{}, common.ErrNotImplementedError
  121. }
  122. func KernelVersionWithContext(ctx context.Context) (string, error) {
  123. _, _, version, err := PlatformInformationWithContext(ctx)
  124. return version, err
  125. }