package gotoc import ( "unsafe" "fmt" "strconv" "github.com/vmware/leap/util" log "github.com/jbrodriguez/mlog" ) /* #include "../../../../../Include/sigar.h" */ import "C" func Ps() ([]C.sigar_proc_state_t , []C.sigar_proc_time_t, []C.sigar_proc_mem_t, []C.sigar_proc_disk_io_t, []C.sigar_proc_cumulative_disk_io_t, []C.sigar_proc_cred_t, []C.sigar_proc_cred_name_t, []C.sigar_proc_cpu_t, []C.sigar_proc_args_t, []C.sigar_proc_fd_t, []C.sigar_proc_exe_t){ sigar:=GetSigarHandle() var procList C.sigar_proc_list_t C.sigar_proc_list_get(sigar, &procList) var length int=int(procList.number) var pstate =make([]C.sigar_proc_state_t, length) var ptime =make([]C.sigar_proc_time_t,length) var pmem =make([]C.sigar_proc_mem_t,length) var pdiskio =make([]C.sigar_proc_disk_io_t,length) var pcumdiskio =make([]C.sigar_proc_cumulative_disk_io_t,length) var pcred =make([]C.sigar_proc_cred_t,length) var pcredname =make([]C.sigar_proc_cred_name_t,length) var pcpu =make([]C.sigar_proc_cpu_t,length) var pargs =make([]C.sigar_proc_args_t,length) var pfd =make([]C.sigar_proc_fd_t,length) var pexe =make([]C.sigar_proc_exe_t,length) cpid:=GetGoSlice(length, unsafe.Pointer(procList.data)) var goPid []C.sigar_pid_t goPid = *(*[]C.sigar_pid_t)(unsafe.Pointer(&cpid)) for i:=0;i 0 { newSize := noOfProcesses-errors procInfos = append(([]*ProcessInfo)(nil), procInfos[:newSize]...) log.ErrorS("%v errors have occurred, prunning array size from %v to %v index is: %v, newSize: %v", errors, noOfProcesses, newSize, index, len(procInfos)) } return &ProcessInfoList { procInfos, sysMemInfoOut },nil } //--------------------------------------------------------------------------- //ProcInfo ProcInfo ProcInfo ProcInfo ProcInfo ProcInfo ProcInfo ProcInfo //--------------------------------------------------------------------------- type ProcInfoType uint64 const ( MEM ProcInfoType = 1 << iota CPU TIME DISK ARGS STATE CRED_NAME ) type ProcessInfoList struct { Processes []*ProcessInfo SysMemInfo *MemInfo } type ProcessInfo struct { Pid uint64 Args []string State *ProcessStateInfo CredName *ProcessCredName Mem *ProcessMemInfo Cpu *ProcessCpuInfo Disk *ProcessDiskInfo Error error } type ProcessCredName struct { User string Group string } type ProcessStateInfo struct { Name string State rune Tty int Priority int Nice int Processor int Threads uint64 } type ProcessMemInfo struct { Size uint64 Resident uint64 Share uint64 MinorFaults uint64 MajorFaults uint64 PageFaults uint64 Percent float64 } type ProcessCpuInfo struct { StartTime uint64 User uint64 Sys uint64 Total uint64 LastTime uint64 Percent float64 } type ProcessDiskInfo struct{ //sigar_proc_cumulative_disk_io_t BytesRead uint64 BytesWritten uint64 BytesTotal uint64 } func _getProcInfo(pid uint64, infoTypesMask ProcInfoType, sysMemInfoIn *MemInfo, sigar *C.sigar_t) (procInfo *ProcessInfo, sysMemInfo *MemInfo, err error) { procInfo = &ProcessInfo{ Pid : pid } sigarPid := C.sigar_pid_t(pid) if infoTypesMask&MEM != 0 { sysMemInfo = sysMemInfoIn if sysMemInfo == nil { sysMemInfo,err = GetMemInfo() if err != nil { return nil,nil,err } } if err = _populateProcessMemInfo(sigarPid, procInfo, sysMemInfo, sigar) ; err != nil { return nil,nil,err } } if infoTypesMask&CPU != 0 { if err = _populateProcessCpuInfo(sigarPid, procInfo, sigar) ; err != nil { return nil,nil,err } } if infoTypesMask&TIME != 0 { } if infoTypesMask&DISK != 0 { if err = _populateProcessDiskInfo(sigarPid, procInfo, sigar) ; err != nil { return nil,nil,err } } if infoTypesMask&ARGS != 0 { if err = _populateProcessArgs(sigarPid, procInfo, sigar) ; err != nil { return nil,nil,err } } if infoTypesMask&STATE != 0 { if err = _populateProcessState(sigarPid, procInfo, sigar) ; err != nil { return nil,nil,err } } if infoTypesMask&CRED_NAME != 0 { if err = _populateProcessCredName(sigarPid, procInfo, sigar) ; err != nil { return nil,nil,err } } return procInfo,sysMemInfo,nil } func _populateProcessMemInfo(pid C.sigar_pid_t, procInfo *ProcessInfo, sysMemInfo *MemInfo, sigar *C.sigar_t) error { var procMem C.sigar_proc_mem_t status := int(C.sigar_proc_mem_get(sigar, pid, &procMem)) if status != SIGAR_OK { return fmt.Errorf("Failed to rertieve proc mem info for pid: "+ strconv.FormatUint(procInfo.Pid,10) +" with error: " + strconv.Itoa(status)) } procInfo.Mem = &ProcessMemInfo{ Size : uint64(procMem.size), Resident : uint64(procMem.resident), Share : uint64(procMem.share), MinorFaults : uint64(procMem.minor_faults), MajorFaults : uint64(procMem.major_faults), PageFaults : uint64(procMem.page_faults), } procInfo.Mem.Percent = float64(sysMemInfo.Mem.Total/procInfo.Mem.Resident) return nil } func _populateProcessCpuInfo(pid C.sigar_pid_t, procInfo *ProcessInfo, sigar *C.sigar_t) error { var procCpu C.sigar_proc_cpu_t status := int(C.sigar_proc_cpu_get(sigar, pid, &procCpu)) if status != SIGAR_OK { return fmt.Errorf("Failed to rertieve proc mem info for pid: %v", procInfo.Pid) } procInfo.Cpu = &ProcessCpuInfo{ StartTime : uint64(procCpu.start_time), User : uint64(procCpu.user), Sys : uint64(procCpu.sys), Total : uint64(procCpu.total), LastTime : uint64(procCpu.last_time), Percent : float64(procCpu.percent), } return nil } func _populateProcessDiskInfo(pid C.sigar_pid_t, procInfo *ProcessInfo, sigar *C.sigar_t) error { var c_procDiskIo C.sigar_proc_disk_io_t status := int(C.sigar_proc_disk_io_get(sigar, pid, &c_procDiskIo)) if status != SIGAR_OK { //TODO: restore error (unsupported on mac) //return fmt.Errorf("Failed to rertieve proc disk io info for pid: %v with error: %v", procInfo.Pid, status) procInfo.Disk = &ProcessDiskInfo{ BytesRead : 100000, BytesWritten : 23423432, BytesTotal : 2345543, } } procInfo.Disk = &ProcessDiskInfo{ BytesRead : uint64(c_procDiskIo.bytes_read), BytesWritten : uint64(c_procDiskIo.bytes_written), BytesTotal : uint64(c_procDiskIo.bytes_total), } return nil } func _populateProcessArgs(pid C.sigar_pid_t, procInfo *ProcessInfo, sigar *C.sigar_t) error { var c_procArgs C.sigar_proc_args_t defer C.sigar_proc_args_destroy(sigar, &c_procArgs) status := int(C.sigar_proc_args_get(sigar, pid, &c_procArgs)) if status != SIGAR_OK { return fmt.Errorf("error: proc args for pid: " + strconv.FormatUint(procInfo.Pid ,10)) } noOfArgs := int(c_procArgs.number) args := *(*[]*C.char) (CArr2SlicePtr(noOfArgs, c_procArgs.data)) procInfo.Args = make([]string, noOfArgs) for i,arg := range args { procInfo.Args[i] = C.GoString(arg) } return nil } func _populateProcessState(pid C.sigar_pid_t, procInfo *ProcessInfo, sigar *C.sigar_t) error { var c_procState C.sigar_proc_state_t status := int(C.sigar_proc_state_get(sigar, pid, &c_procState)) if status != SIGAR_OK { return fmt.Errorf("Failed to rertieve proc state info for pid: %v", procInfo.Pid) } procInfo.State = &ProcessStateInfo{ Name : C.GoString(&c_procState.name[0]), State: rune(c_procState.state), Tty : int(c_procState.tty), Priority : int(c_procState.priority), Nice : int(c_procState.nice), Processor : int(c_procState.processor), Threads : uint64(c_procState.threads), } return nil } var c_credName C.sigar_proc_cred_name_t func _populateProcessCredName(pid C.sigar_pid_t, procInfo *ProcessInfo, sigar *C.sigar_t) error { status := int(C.sigar_proc_cred_name_get(sigar, pid, &c_credName)) if status != SIGAR_OK { return fmt.Errorf("Failed to rertieve proc cred name for pid: %v", procInfo.Pid) } procInfo.CredName = &ProcessCredName{ User : C.GoString(&c_credName.user[0]), Group : C.GoString(&c_credName.group[0]), } return nil }