1
0
mirror of https://github.com/shirou/gopsutil.git synced 2025-04-28 13:48:49 +08:00
shirou_gopsutil/host/host_openbsd.go
fG! ab33d5ec89
Fix wrong user count
There are empty entries in OpenBSD's utmp that have a line and time entry but no user logged in (the entry is "cleared" after user logs out but not totally as expected in the code here). Current checks are insufficient so check if Name field is empty and skip in that case.
2020-12-13 00:34:27 +00:00

105 lines
2.2 KiB
Go

// +build openbsd
package host
import (
"bytes"
"context"
"encoding/binary"
"io/ioutil"
"os"
"strings"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/process"
"golang.org/x/sys/unix"
)
const (
UTNameSize = 32 /* see MAXLOGNAME in <sys/param.h> */
UTLineSize = 8
UTHostSize = 16
)
func HostIDWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func numProcs(ctx context.Context) (uint64, error) {
procs, err := process.PidsWithContext(ctx)
if err != nil {
return 0, err
}
return uint64(len(procs)), nil
}
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
platform := ""
family := ""
version := ""
p, err := unix.Sysctl("kern.ostype")
if err == nil {
platform = strings.ToLower(p)
}
v, err := unix.Sysctl("kern.osrelease")
if err == nil {
version = strings.ToLower(v)
}
return platform, family, version, nil
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
var ret []UserStat
utmpfile := "/var/run/utmp"
file, err := os.Open(utmpfile)
if err != nil {
return ret, err
}
defer file.Close()
buf, err := ioutil.ReadAll(file)
if err != nil {
return ret, err
}
u := Utmp{}
entrySize := int(unsafe.Sizeof(u))
count := len(buf) / entrySize
for i := 0; i < count; i++ {
b := buf[i*entrySize : i*entrySize+entrySize]
var u Utmp
br := bytes.NewReader(b)
err := binary.Read(br, binary.LittleEndian, &u)
if err != nil || u.Time == 0 || u.Name[0] == 0 {
continue
}
user := UserStat{
User: common.IntToString(u.Name[:]),
Terminal: common.IntToString(u.Line[:]),
Host: common.IntToString(u.Host[:]),
Started: int(u.Time),
}
ret = append(ret, user)
}
return ret, nil
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
_, _, version, err := PlatformInformationWithContext(ctx)
return version, err
}