From 20c3ddbfe528ec30c19d786875383d7753702a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=A5=E5=B1=B1=E5=8F=B2=E9=83=8E?= Date: Fri, 6 Mar 2015 10:05:58 +0900 Subject: [PATCH] process: fix darwin kinfo_proc struct and introduce creation by godef. --- process/process_darwin.go | 45 ++++++++++++++++++++++++++++------------- process/process_darwin_amd64.go | 32 ++++++++++++++--------------- process/process_test.go | 31 ++++++++++++++++++---------- process/types_darwin.go | 3 +++ 4 files changed, 69 insertions(+), 42 deletions(-) diff --git a/process/process_darwin.go b/process/process_darwin.go index 837512c..210e14f 100644 --- a/process/process_darwin.go +++ b/process/process_darwin.go @@ -4,6 +4,7 @@ package process import ( "bytes" + "syscall" "unsafe" common "github.com/shirou/gopsutil/common" @@ -21,6 +22,10 @@ const ( KernProcPathname = 12 // path to executable ) +type _Ctype_struct___0 struct { + Pad uint64 +} + // MemoryInfoExStat is different between OSes type MemoryInfoExStat struct { } @@ -43,8 +48,6 @@ func Pids() ([]int32, error) { } func (p *Process) Ppid() (int32, error) { - return 0, common.NotImplementedError - k, err := p.getKProc() if err != nil { return 0, err @@ -64,7 +67,7 @@ func (p *Process) Exe() (string, error) { return "", common.NotImplementedError } func (p *Process) Cmdline() (string, error) { - return "", common.NotImplementedError + return p.Name() } func (p *Process) CreateTime() (int64, error) { return 0, common.NotImplementedError @@ -122,7 +125,11 @@ func (p *Process) Terminal() (string, error) { return termmap[ttyNr], nil } func (p *Process) Nice() (int32, error) { - return 0, common.NotImplementedError + k, err := p.getKProc() + if err != nil { + return 0, err + } + return int32(k.Proc.P_nice), nil } func (p *Process) IOnice() (int32, error) { return 0, common.NotImplementedError @@ -210,7 +217,7 @@ func copyParams(k *KinfoProc, p *Process) error { func processes() ([]Process, error) { results := make([]Process, 0, 50) - mib := []int32{CTLKern, KernProc, KernProcAll} + mib := []int32{CTLKern, KernProc, KernProcAll, 0} buf, length, err := common.CallSyscall(mib) if err != nil { return results, err @@ -220,9 +227,15 @@ func processes() ([]Process, error) { k := KinfoProc{} procinfoLen := int(unsafe.Sizeof(k)) count := int(length / uint64(procinfoLen)) + /* + fmt.Println(length, procinfoLen, count) + b := buf[0*procinfoLen : 0*procinfoLen+procinfoLen] + fmt.Println(b) + kk, err := parseKinfoProc(b) + fmt.Printf("%#v", kk) + */ // parse buf to procs - for i := 0; i < count; i++ { b := buf[i*procinfoLen : i*procinfoLen+procinfoLen] k, err := parseKinfoProc(b) @@ -255,16 +268,20 @@ func parseKinfoProc(buf []byte) (KinfoProc, error) { func (p *Process) getKProc() (*KinfoProc, error) { mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid} - - buf, length, err := common.CallSyscall(mib) - if err != nil { - return nil, err - } procK := KinfoProc{} - if length != uint64(unsafe.Sizeof(procK)) { - return nil, err + length := uint64(unsafe.Sizeof(procK)) + buf := make([]byte, length) + _, _, syserr := syscall.Syscall6( + syscall.SYS___SYSCTL, + uintptr(unsafe.Pointer(&mib[0])), + uintptr(len(mib)), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&length)), + 0, + 0) + if syserr != 0 { + return nil, syserr } - k, err := parseKinfoProc(buf) if err != nil { return nil, err diff --git a/process/process_darwin_amd64.go b/process/process_darwin_amd64.go index 467de07..7ac7bdd 100644 --- a/process/process_darwin_amd64.go +++ b/process/process_darwin_amd64.go @@ -1,7 +1,5 @@ -// +build darwin -// +build amd64 // Created by cgo -godefs - DO NOT EDIT -// cgo -godefs process/types_darwin.go +// cgo -godefs types_darwin.go package process @@ -63,7 +61,7 @@ type KinfoProc struct { } type Eproc struct { - Paddr *Proc + Paddr *uint64 Sess *Session Pcred Upcred Ucred Uucred @@ -94,7 +92,7 @@ type Proc struct{} type Session struct{} type ucred struct { - Link UcredQueue + Link _Ctype_struct___0 Ref uint64 Posix Posix_cred Label *Label @@ -133,25 +131,25 @@ type Sigacts struct{} type ExternProc struct { P_un [16]byte - P_vmspace *Vmspace - P_sigacts *Sigacts + P_vmspace uint64 + P_sigacts uint64 + Pad_cgo_0 [3]byte P_flag int32 P_stat int8 - Pad_cgo_0 [3]byte P_pid int32 P_oppid int32 P_dupfd int32 Pad_cgo_1 [4]byte - User_stack *int8 - Exit_thread *byte + User_stack uint64 + Exit_thread uint64 P_debugger int32 Sigwait int32 P_estcpu uint32 P_cpticks int32 P_pctcpu uint32 Pad_cgo_2 [4]byte - P_wchan *byte - P_wmesg *int8 + P_wchan uint64 + P_wmesg uint64 P_swtime uint32 P_slptime uint32 P_realtimer Itimerval @@ -161,10 +159,10 @@ type ExternProc struct { P_iticks uint64 P_traceflag int32 Pad_cgo_3 [4]byte - P_tracep *Vnode + P_tracep uint64 P_siglist int32 Pad_cgo_4 [4]byte - P_textvp *Vnode + P_textvp uint64 P_holdcnt int32 P_sigmask uint32 P_sigignore uint32 @@ -174,12 +172,12 @@ type ExternProc struct { P_nice int8 P_comm [17]int8 Pad_cgo_5 [4]byte - P_pgrp *Pgrp - P_addr *UserStruct + P_pgrp uint64 + P_addr uint64 P_xstat uint16 P_acflag uint16 Pad_cgo_6 [4]byte - P_ru *Rusage + P_ru uint64 } type Itimerval struct { diff --git a/process/process_test.go b/process/process_test.go index 2d4e9e6..8375e17 100644 --- a/process/process_test.go +++ b/process/process_test.go @@ -8,7 +8,7 @@ import ( ) func testGetProcess() Process { - checkPid := os.Getpid() + checkPid := os.Getpid() // process.test if runtime.GOOS == "windows" { checkPid = 7960 } @@ -27,10 +27,7 @@ func Test_Pids(t *testing.T) { } func Test_Pid_exists(t *testing.T) { - checkPid := 1 - if runtime.GOOS == "windows" { - checkPid = 0 - } + checkPid := os.Getpid() ret, err := PidExists(int32(checkPid)) if err != nil { @@ -38,16 +35,15 @@ func Test_Pid_exists(t *testing.T) { } if ret == false { - t.Errorf("could not get init process %v", ret) + t.Errorf("could not get process exists %v", ret) } } func Test_NewProcess(t *testing.T) { - checkPid := 1 + checkPid := os.Getpid() if runtime.GOOS == "windows" { checkPid = 0 } - ret, err := NewProcess(int32(checkPid)) if err != nil { t.Errorf("error %v", err) @@ -91,7 +87,6 @@ func Test_Process_Ppid(t *testing.T) { if v == 0 { t.Errorf("return value is 0 %v", v) } - } func Test_Process_IOCounters(t *testing.T) { @@ -121,10 +116,24 @@ func Test_Process_NumCtx(t *testing.T) { func Test_Process_Nice(t *testing.T) { p := testGetProcess() - _, err := p.Nice() + n, err := p.Nice() if err != nil { t.Errorf("geting nice error %v", err) - return + } + if n != 0 { + t.Errorf("invalid nice: %d", n) + } +} + +func Test_Process_Name(t *testing.T) { + p := testGetProcess() + + n, err := p.Name() + if err != nil { + t.Errorf("geting name error %v", err) + } + if n != "process.test" { + t.Errorf("invalid name %s", n) } } diff --git a/process/types_darwin.go b/process/types_darwin.go index 0326d38..21216cd 100644 --- a/process/types_darwin.go +++ b/process/types_darwin.go @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// Hand Writing +// - all pointer in ExternProc to uint64 + // +build ignore /*