mirror of
https://github.com/shirou/gopsutil.git
synced 2025-04-24 13:48:56 +08:00
implements users() on linux.
This commit is contained in:
parent
1629dd9a38
commit
77fb50adf6
18
common.go
18
common.go
@ -10,6 +10,7 @@ import (
|
||||
"bufio"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
)
|
||||
|
||||
// Read contents from file and split by new line.
|
||||
@ -31,3 +32,20 @@ func ReadLines(filename string) ([]string, error) {
|
||||
|
||||
return ret, err
|
||||
}
|
||||
|
||||
|
||||
func byteToString(orig []byte) string{
|
||||
n := -1
|
||||
for i, b := range orig {
|
||||
if b == 0 {
|
||||
break
|
||||
}
|
||||
n = i + 1
|
||||
}
|
||||
if n == -1{
|
||||
return string(orig)
|
||||
}else{
|
||||
return string(orig[:n])
|
||||
}
|
||||
|
||||
}
|
||||
|
7
host.go
7
host.go
@ -7,3 +7,10 @@ type HostInfoStat struct {
|
||||
Uptime int64 `json:"uptime"`
|
||||
Procs uint64 `json:"procs"`
|
||||
}
|
||||
|
||||
type UserStat struct {
|
||||
User string `json:"user"`
|
||||
Terminal string `json:"terminal"`
|
||||
Host string `json:"host"`
|
||||
Started int `json:"started"`
|
||||
}
|
||||
|
@ -1,12 +1,39 @@
|
||||
// +build linux
|
||||
// +build linux,amd64
|
||||
|
||||
package gopsutil
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type exit_status struct {
|
||||
E_termination int16 // Process termination status.
|
||||
E_exit int16 // Process exit status.
|
||||
}
|
||||
type timeval struct {
|
||||
Tv_sec uint32 // Seconds.
|
||||
Tv_usec uint32 // Microseconds.
|
||||
}
|
||||
|
||||
type utmp struct {
|
||||
Ut_type int16 // Type of login.
|
||||
Ut_pid int32 // Process ID of login process.
|
||||
Ut_line [32]byte // Devicename.
|
||||
Ut_id [4]byte // Inittab ID.
|
||||
Ut_user [32]byte // Username.
|
||||
Ut_host [256]byte // Hostname for remote login.
|
||||
Ut_exit exit_status // Exit status of a process marked
|
||||
Ut_session int32 // Session ID, used for windowing.
|
||||
Ut_tv timeval // Time entry was made.
|
||||
Ut_addr_v6 [16]byte // Internet address of remote host.
|
||||
Unused [20]byte // Reserved for future use. // original is 20
|
||||
}
|
||||
|
||||
func HostInfo() (HostInfoStat, error) {
|
||||
ret := HostInfoStat{}
|
||||
|
||||
@ -19,11 +46,50 @@ func HostInfo() (HostInfoStat, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
||||
func Boot_time() (int64, error){
|
||||
func Boot_time() (int64, error) {
|
||||
sysinfo := &syscall.Sysinfo_t{}
|
||||
if err := syscall.Sysinfo(sysinfo); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return sysinfo.Uptime, nil
|
||||
}
|
||||
|
||||
func Users() ([]UserStat, error) {
|
||||
utmpfile := "/var/run/utmp"
|
||||
ret := make([]UserStat, 0)
|
||||
|
||||
file, err := os.Open(utmpfile)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
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 {
|
||||
continue
|
||||
}
|
||||
user := UserStat{
|
||||
User: byteToString(u.Ut_user[:]),
|
||||
Terminal: byteToString(u.Ut_line[:]),
|
||||
Host: byteToString(u.Ut_host[:]),
|
||||
Started: int(u.Ut_tv.Tv_sec),
|
||||
}
|
||||
ret = append(ret, user)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
|
||||
}
|
||||
|
13
host_test.go
13
host_test.go
@ -23,3 +23,16 @@ func TestBoot_time(t *testing.T) {
|
||||
t.Errorf("Could not boot time %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func TestUsers(t *testing.T) {
|
||||
v, err := Users()
|
||||
if err != nil {
|
||||
t.Errorf("error %v", err)
|
||||
}
|
||||
for _, u := range v {
|
||||
if u.User == ""{
|
||||
t.Errorf("Could not Users %v", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user