diff --git a/process/process_freebsd.go b/process/process_freebsd.go index a5f0435..ecd8920 100644 --- a/process/process_freebsd.go +++ b/process/process_freebsd.go @@ -6,6 +6,8 @@ import ( "bytes" "encoding/binary" "unsafe" + "strings" + "syscall" cpu "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/internal/common" @@ -53,7 +55,19 @@ func (p *Process) Exe() (string, error) { return "", common.NotImplementedError } func (p *Process) Cmdline() (string, error) { - return "", common.NotImplementedError + mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid} + buf, _, err := common.CallSyscall(mib) + if err != nil { + return "", err + } + ret := strings.FieldsFunc(string(buf), func(r rune) bool { + if r == '\u0000' { + return true + } + return false + }) + + return strings.Join(ret, " "), nil } func (p *Process) CreateTime() (int64, error) { return 0, common.NotImplementedError @@ -121,7 +135,14 @@ func (p *Process) Rlimit() ([]RlimitStat, error) { return rlimit, common.NotImplementedError } func (p *Process) IOCounters() (*IOCountersStat, error) { - return nil, common.NotImplementedError + k, err := p.getKProc() + if err != nil { + return nil, err + } + return &IOCountersStat{ + ReadCount: uint64(k.KiRusage.Inblock), + WriteCount: uint64(k.KiRusage.Oublock), + }, nil } func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) { return nil, common.NotImplementedError @@ -142,7 +163,15 @@ func (p *Process) Threads() (map[string]string, error) { return ret, common.NotImplementedError } func (p *Process) CPUTimes() (*cpu.CPUTimesStat, error) { - return nil, common.NotImplementedError + k, err := p.getKProc() + if err != nil { + return nil, err + } + return &cpu.CPUTimesStat{ + CPU: "cpu", + User: float64(k.KiRusage.Utime.Sec) + float64(k.KiRusage.Utime.Usec)/1000000, + System: float64(k.KiRusage.Stime.Sec) + float64(k.KiRusage.Stime.Usec)/1000000, + }, nil } func (p *Process) CPUAffinity() ([]int32, error) { return nil, common.NotImplementedError @@ -152,13 +181,16 @@ func (p *Process) MemoryInfo() (*MemoryInfoStat, error) { if err != nil { return nil, err } - - ret := &MemoryInfoStat{ - RSS: uint64(k.KiRssize), - VMS: uint64(k.KiSize), + v, err := syscall.Sysctl("vm.stats.vm.v_page_size") + if err != nil { + return nil, err } + pageSize := binary.LittleEndian.Uint16([]byte(v)) - return ret, nil + return &MemoryInfoStat{ + RSS: uint64(k.KiRssize) * uint64(pageSize), + VMS: uint64(k.KiSize), + }, nil } func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) { return nil, common.NotImplementedError @@ -241,11 +273,7 @@ func parseKinfoProc(buf []byte) (KinfoProc, error) { var k KinfoProc br := bytes.NewReader(buf) err := binary.Read(br, binary.LittleEndian, &k) - if err != nil { - return k, err - } - - return k, nil + return k, err } func (p *Process) getKProc() (*KinfoProc, error) { diff --git a/process/process_freebsd_386.go b/process/process_freebsd_386.go index 4d9ebfd..6b3bdfc 100644 --- a/process/process_freebsd_386.go +++ b/process/process_freebsd_386.go @@ -10,8 +10,38 @@ const ( KernProcPID = 1 // by process id KernProcProc = 8 // only return procs KernProcPathname = 12 // path to executable + KernProcArgs = 7 // get/set arguments/proctitle ) +type Timespec struct { + Sec int32 + Nsec int32 +} + +type Timeval struct { + Sec int32 + Usec int32 +} + +type Rusage struct { + Utime Timeval + Stime Timeval + Maxrss int32 + Ixrss int32 + Idrss int32 + Isrss int32 + Minflt int32 + Majflt int32 + Nswap int32 + Inblock int32 + Oublock int32 + Msgsnd int32 + Msgrcv int32 + Nsignals int32 + Nvcsw int32 + Nivcsw int32 +} + // copied from sys/user.h type KinfoProc struct { KiStructsize int32 @@ -83,7 +113,7 @@ type KinfoProc struct { KiNumthreads int32 KiTid int32 KiPri int32 - KiRusage [72]byte + KiRusage Rusage KiRusageCh [72]byte KiPcb int32 KiKstack int32 diff --git a/process/process_freebsd_amd64.go b/process/process_freebsd_amd64.go index 0dafda2..69a352f 100644 --- a/process/process_freebsd_amd64.go +++ b/process/process_freebsd_amd64.go @@ -1,6 +1,5 @@ // +build freebsd // +build amd64 - package process // copied from sys/sysctl.h @@ -10,8 +9,38 @@ const ( KernProcPID = 1 // by process id KernProcProc = 8 // only return procs KernProcPathname = 12 // path to executable + KernProcArgs = 7 // get/set arguments/proctitle ) +type Timespec struct { + Sec int64 + Nsec int64 +} + +type Timeval struct { + Sec int64 + Usec int64 +} + +type Rusage struct { + Utime Timeval + Stime Timeval + Maxrss int64 + Ixrss int64 + Idrss int64 + Isrss int64 + Minflt int64 + Majflt int64 + Nswap int64 + Inblock int64 + Oublock int64 + Msgsnd int64 + Msgrcv int64 + Nsignals int64 + Nvcsw int64 + Nivcsw int64 +} + // copied from sys/user.h type KinfoProc struct { KiStructsize int32 @@ -83,7 +112,7 @@ type KinfoProc struct { KiNumthreads int32 KiTid int32 KiPri int32 - KiRusage [144]byte + KiRusage Rusage KiRusageCh [144]byte KiPcb int64 KiKstack int64