From 4973aa73f97d5d064590b29192e9f9a3369a3217 Mon Sep 17 00:00:00 2001 From: Shirou WAKAYAMA Date: Wed, 31 Dec 2014 00:13:52 +0900 Subject: [PATCH] start to use godefs to get C structs. --- .gitignore | 1 + mktypes.sh | 37 +++++ process/process_darwin.go | 43 ++++-- process/process_darwin_amd64.go | 313 +++++++++++++++++++++++++++++----------- process/types_darwin.go | 157 ++++++++++++++++++++ 5 files changed, 450 insertions(+), 101 deletions(-) create mode 100644 mktypes.sh create mode 100644 process/types_darwin.go diff --git a/.gitignore b/.gitignore index 1f2308d..9204bd2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *~ #* +_obj diff --git a/mktypes.sh b/mktypes.sh new file mode 100644 index 0000000..7bf2e24 --- /dev/null +++ b/mktypes.sh @@ -0,0 +1,37 @@ + +DIRS="cpu disk docker host load mem net process" + +GOOS=`uname | tr '[:upper:]' '[:lower:]'` +ARCH=`uname -m` + +case $ARCH in + amd64) + GOARCH="amd64" + ;; + x86_64) + GOARCH="amd64" + ;; + i386) + GOARCH="386" + ;; + i686) + GOARCH="386" + ;; + arm) + GOARCH="arm" + ;; + *) + echo "unknown arch: $ARCH" + exit 1 +esac + +for DIR in $DIRS +do + if [ -e ${DIR}/types_${GOOS}.go ]; then + echo "// +build $GOOS" > ${DIR}/${DIR}_${GOOS}_${GOARCH}.go + echo "// +build $GOARCH" >> ${DIR}/${DIR}_${GOOS}_${GOARCH}.go + go tool cgo -godefs ${DIR}/types_${GOOS}.go >> ${DIR}/${DIR}_${GOOS}_${GOARCH}.go + fi +done + + diff --git a/process/process_darwin.go b/process/process_darwin.go index 8c62adf..43f2e20 100644 --- a/process/process_darwin.go +++ b/process/process_darwin.go @@ -13,6 +13,16 @@ import ( net "github.com/shirou/gopsutil/net" ) +// copied from sys/sysctl.h +const ( + CTLKern = 1 // "high kernel": proc, limits + KernProc = 14 // struct: process entries + KernProcPID = 1 // by process id + KernProcProc = 8 // only return procs + KernProcAll = 0 // everything + KernProcPathname = 12 // path to executable +) + // MemoryInfoExStat is different between OSes type MemoryInfoExStat struct { } @@ -42,7 +52,7 @@ func (p *Process) Ppid() (int32, error) { return 0, err } - return k.KiPpid, nil + return k.Proc.P_pid, nil } func (p *Process) Name() (string, error) { k, err := p.getKProc() @@ -50,7 +60,7 @@ func (p *Process) Name() (string, error) { return "", err } - return string(k.KiComm[:]), nil + return common.IntToString(k.Proc.P_comm[:]), nil } func (p *Process) Exe() (string, error) { return "", common.NotImplementedError @@ -73,7 +83,7 @@ func (p *Process) Status() (string, error) { return "", err } - return string(k.KiStat[:]), nil + return string(k.Proc.P_stat), nil // TODO } func (p *Process) Uids() ([]int32, error) { k, err := p.getKProc() @@ -83,7 +93,7 @@ func (p *Process) Uids() ([]int32, error) { uids := make([]int32, 0, 3) - uids = append(uids, int32(k.KiRuid), int32(k.KiUID), int32(k.KiSvuid)) + uids = append(uids, int32(k.Eproc.Pcred.P_ruid), int32(k.Eproc.Ucred.Uid), int32(k.Eproc.Pcred.P_svuid)) return uids, nil } @@ -94,7 +104,7 @@ func (p *Process) Gids() ([]int32, error) { } gids := make([]int32, 0, 3) - gids = append(gids, int32(k.KiRgid), int32(k.KiNgroups[0]), int32(k.KiSvuid)) + gids = append(gids, int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Ucred.Ngroups), int32(k.Eproc.Pcred.P_svgid)) return gids, nil } @@ -104,7 +114,7 @@ func (p *Process) Terminal() (string, error) { return "", err } - ttyNr := uint64(k.KiTdev) + ttyNr := uint64(k.Eproc.Tdev) termmap, err := getTerminalMap() if err != nil { @@ -133,12 +143,16 @@ func (p *Process) NumFDs() (int32, error) { return 0, common.NotImplementedError } func (p *Process) NumThreads() (int32, error) { - k, err := p.getKProc() - if err != nil { - return 0, err - } + return 0, common.NotImplementedError - return k.KiNumthreads, nil + /* + k, err := p.getKProc() + if err != nil { + return 0, err + } + + return k.KiNumthreads, nil + */ } func (p *Process) Threads() (map[string]string, error) { ret := make(map[string]string, 0) @@ -160,8 +174,8 @@ func (p *Process) MemoryInfo() (*MemoryInfoStat, error) { } ret := &MemoryInfoStat{ - RSS: uint64(k.KiRssize), - VMS: uint64(k.KiSize), + RSS: uint64(k.Eproc.Xrssize), + VMS: uint64(k.Eproc.Xsize), } return ret, nil @@ -220,7 +234,7 @@ func processes() ([]Process, error) { if err != nil { continue } - p, err := NewProcess(int32(k.KiPid)) + p, err := NewProcess(int32(k.Proc.P_pid)) if err != nil { continue } @@ -235,6 +249,7 @@ func processes() ([]Process, error) { 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 diff --git a/process/process_darwin_amd64.go b/process/process_darwin_amd64.go index 07308a6..467de07 100644 --- a/process/process_darwin_amd64.go +++ b/process/process_darwin_amd64.go @@ -1,97 +1,236 @@ // +build darwin // +build amd64 +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs process/types_darwin.go package process -// copied from sys/sysctl.h const ( - CTLKern = 1 // "high kernel": proc, limits - KernProc = 14 // struct: process entries - KernProcPID = 1 // by process id - KernProcProc = 8 // only return procs - KernProcAll = 0 // everything - KernProcPathname = 12 // path to executable + sizeofPtr = 0x8 + sizeofShort = 0x2 + sizeofInt = 0x4 + sizeofLong = 0x8 + sizeofLongLong = 0x8 ) -// copied from sys/user.h +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 +) + +type Timespec struct { + Sec int64 + Nsec int64 +} + +type Timeval struct { + Sec int64 + Usec int32 + Pad_cgo_0 [4]byte +} + +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 +} + +type Rlimit struct { + Cur uint64 + Max uint64 +} + +type UGid_t uint32 + type KinfoProc struct { - KiStructsize int32 - KiLayout int32 - KiArgs int64 - KiPaddr int64 - KiAddr int64 - KiTracep int64 - KiTextvp int64 - KiFd int64 - KiVmspace int64 - KiWchan int64 - KiPid int32 - KiPpid int32 - KiPgid int32 - KiTpgid int32 - KiSid int32 - KiTsid int32 - KiJobc [2]byte - KiSpareShort1 [2]byte - KiTdev int32 - KiSiglist [16]byte - KiSigmask [16]byte - KiSigignore [16]byte - KiSigcatch [16]byte - KiUID int32 - KiRuid int32 - KiSvuid int32 - KiRgid int32 - KiSvgid int32 - KiNgroups [2]byte - KiSpareShort2 [2]byte - KiGroups [64]byte - KiSize int64 - KiRssize int64 - KiSwrss int64 - KiTsize int64 - KiDsize int64 - KiSsize int64 - KiXstat [2]byte - KiAcflag [2]byte - KiPctcpu int32 - KiEstcpu int32 - KiSlptime int32 - KiSwtime int32 - KiCow int32 - KiRuntime int64 - KiStart [16]byte - KiChildtime [16]byte - KiFlag int64 - KiKflag int64 - KiTraceflag int32 - KiStat [1]byte - KiNice [1]byte - KiLock [1]byte - KiRqindex [1]byte - KiOncpu [1]byte - KiLastcpu [1]byte - KiOcomm [17]byte - KiWmesg [9]byte - KiLogin [18]byte - KiLockname [9]byte - KiComm [20]byte - KiEmul [17]byte - KiSparestrings [68]byte - KiSpareints [36]byte - KiCrFlags int32 - KiJid int32 - KiNumthreads int32 - KiTid int32 - KiPri int32 - KiRusage [144]byte - KiRusageCh [144]byte - KiPcb int64 - KiKstack int64 - KiUdata int64 - KiTdaddr int64 - KiSpareptrs [48]byte - KiSpareint64s [96]byte - KiSflag int64 - KiTdflags int64 + Proc ExternProc + Eproc Eproc +} + +type Eproc struct { + Paddr *Proc + Sess *Session + Pcred Upcred + Ucred Uucred + Pad_cgo_0 [4]byte + Vm Vmspace + Ppid int32 + Pgid int32 + Jobc int16 + Pad_cgo_1 [2]byte + Tdev int32 + Tpgid int32 + Pad_cgo_2 [4]byte + Tsess *Session + Wmesg [8]int8 + Xsize int32 + Xrssize int16 + Xccount int16 + Xswrss int16 + Pad_cgo_3 [2]byte + Flag int32 + Login [12]int8 + Spare [4]int32 + Pad_cgo_4 [4]byte +} + +type Proc struct{} + +type Session struct{} + +type ucred struct { + Link UcredQueue + Ref uint64 + Posix Posix_cred + Label *Label + Audit Au_session +} + +type Uucred struct { + Ref int32 + Uid uint32 + Ngroups int16 + Pad_cgo_0 [2]byte + Groups [16]uint32 +} + +type Upcred struct { + Pc_lock [72]int8 + Pc_ucred *ucred + P_ruid uint32 + P_svuid uint32 + P_rgid uint32 + P_svgid uint32 + P_refcnt int32 + Pad_cgo_0 [4]byte +} + +type Vmspace struct { + Dummy int32 + Pad_cgo_0 [4]byte + Dummy2 *int8 + Dummy3 [5]int32 + Pad_cgo_1 [4]byte + Dummy4 [3]*int8 +} + +type Sigacts struct{} + +type ExternProc struct { + P_un [16]byte + P_vmspace *Vmspace + P_sigacts *Sigacts + 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 + 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_swtime uint32 + P_slptime uint32 + P_realtimer Itimerval + P_rtime Timeval + P_uticks uint64 + P_sticks uint64 + P_iticks uint64 + P_traceflag int32 + Pad_cgo_3 [4]byte + P_tracep *Vnode + P_siglist int32 + Pad_cgo_4 [4]byte + P_textvp *Vnode + P_holdcnt int32 + P_sigmask uint32 + P_sigignore uint32 + P_sigcatch uint32 + P_priority uint8 + P_usrpri uint8 + P_nice int8 + P_comm [17]int8 + Pad_cgo_5 [4]byte + P_pgrp *Pgrp + P_addr *UserStruct + P_xstat uint16 + P_acflag uint16 + Pad_cgo_6 [4]byte + P_ru *Rusage +} + +type Itimerval struct { + Interval Timeval + Value Timeval +} + +type Vnode struct{} + +type Pgrp struct{} + +type UserStruct struct{} + +type Au_session struct { + Aia_p *AuditinfoAddr + Mask AuMask +} + +type Posix_cred struct { + Uid uint32 + Ruid uint32 + Svuid uint32 + Ngroups int16 + Pad_cgo_0 [2]byte + Groups [16]uint32 + Rgid uint32 + Svgid uint32 + Gmuid uint32 + Flags int32 +} + +type Label struct{} + +type AuditinfoAddr struct { + Auid uint32 + Mask AuMask + Termid AuTidAddr + Asid int32 + Flags uint64 +} +type AuMask struct { + Success uint32 + Failure uint32 +} +type AuTidAddr struct { + Port int32 + Type uint32 + Addr [4]uint32 +} + +type UcredQueue struct { + Next *ucred + Prev **ucred } diff --git a/process/types_darwin.go b/process/types_darwin.go new file mode 100644 index 0000000..0326d38 --- /dev/null +++ b/process/types_darwin.go @@ -0,0 +1,157 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +/* +Input to cgo -godefs. +*/ + +// +godefs map struct_in_addr [4]byte /* in_addr */ +// +godefs map struct_in6_addr [16]byte /* in6_addr */ +// +godefs map struct_ [16]byte /* in6_addr */ + +package process + +/* +#define __DARWIN_UNIX03 0 +#define KERNEL +#define _DARWIN_USE_64_BIT_INODE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + sizeofPtr = sizeof(void*), +}; + +union sockaddr_all { + struct sockaddr s1; // this one gets used for fields + struct sockaddr_in s2; // these pad it out + struct sockaddr_in6 s3; + struct sockaddr_un s4; + struct sockaddr_dl s5; +}; + +struct sockaddr_any { + struct sockaddr addr; + char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; +}; + +struct ucred_queue { + struct ucred *tqe_next; + struct ucred **tqe_prev; + TRACEBUF +}; + +*/ +import "C" + +// Machine characteristics; for internal use. + +const ( + sizeofPtr = C.sizeofPtr + sizeofShort = C.sizeof_short + sizeofInt = C.sizeof_int + sizeofLong = C.sizeof_long + sizeofLongLong = C.sizeof_longlong +) + +// Basic types + +type ( + _C_short C.short + _C_int C.int + _C_long C.long + _C_long_long C.longlong +) + +// Time + +type Timespec C.struct_timespec + +type Timeval C.struct_timeval + +// Processes + +type Rusage C.struct_rusage + +type Rlimit C.struct_rlimit + +type UGid_t C.gid_t + +type KinfoProc C.struct_kinfo_proc + +type Eproc C.struct_eproc + +type Proc C.struct_proc + +type Session C.struct_session + +type ucred C.struct_ucred + +type Uucred C.struct__ucred + +type Upcred C.struct__pcred + +type Vmspace C.struct_vmspace + +type Sigacts C.struct_sigacts + +type ExternProc C.struct_extern_proc + +type Itimerval C.struct_itimerval + +type Vnode C.struct_vnode + +type Pgrp C.struct_pgrp + +type UserStruct C.struct_user + +type Au_session C.struct_au_session + +type Posix_cred C.struct_posix_cred + +type Label C.struct_label + +type AuditinfoAddr C.struct_auditinfo_addr +type AuMask C.struct_au_mask +type AuTidAddr C.struct_au_tid_addr + +// TAILQ(ucred) +type UcredQueue C.struct_ucred_queue