/** * Read all processes to initialize the information tree. * @param reference reference of ProcessTree * @return treesize>0 if succeeded otherwise =0. */ int initprocesstree_sysdep(ProcessTree_T ** reference) { int treesize; size_t size = sizeof(maxslp); char buf[_POSIX2_LINE_MAX]; int mib_proc2[6] = {CTL_KERN, KERN_PROC2, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), 0}; static int mib_maxslp[] = {CTL_VM, VM_MAXSLP}; ProcessTree_T *pt; kvm_t *kvm_handle; static struct kinfo_proc2 *pinfo; if (sysctl(mib_maxslp, 2, &maxslp, &size, NULL, 0) < 0) { LogError("system statistic error -- vm.maxslp failed"); return FALSE; } if (sysctl(mib_proc2, 6, NULL, &size, NULL, 0) == -1) { LogError("system statistic error -- kern.proc2 #1 failed"); return FALSE; } size *= 2; // Add reserve for new processes which were created between calls of sysctl pinfo = CALLOC(1, size); mib_proc2[5] = (int)(size / sizeof(struct kinfo_proc2)); if (sysctl(mib_proc2, 6, pinfo, &size, NULL, 0) == -1) { FREE(pinfo); LogError("system statistic error -- kern.proc2 #2 failed"); return FALSE; } treesize = (int)(size / sizeof(struct kinfo_proc2)); pt = CALLOC(sizeof(ProcessTree_T), treesize); if (! (kvm_handle = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, buf))) { LogError("system statistic error -- kvm_openfiles failed: %s", buf); return FALSE; } for (int i = 0; i < treesize; i++) { pt[i].pid = pinfo[i].p_pid; pt[i].ppid = pinfo[i].p_ppid; pt[i].starttime = pinfo[i].p_ustart_sec; pt[i].cputime = (long)((pinfo[i].p_rtime_sec * 10) + (pinfo[i].p_rtime_usec / 100000)); pt[i].cpu_percent = 0; pt[i].mem_kbyte = (unsigned long)(pinfo[i].p_vm_rssize * pagesize_kbyte); if (pinfo[i].p_stat == SZOMB) pt[i].status_flag |= PROCESS_ZOMBIE; pt[i].time = get_float_time(); char **args; if ((args = kvm_getargv2(kvm_handle, &pinfo[i], 0))) { StringBuffer_T cmdline = StringBuffer_create(64); for (int j = 0; args[j]; j++) StringBuffer_append(cmdline, args[j + 1] ? "%s " : "%s", args[j]); pt[i].cmdline = Str_dup(StringBuffer_toString(StringBuffer_trim(cmdline))); StringBuffer_free(&cmdline); } if (! pt[i].cmdline || ! *pt[i].cmdline) pt[i].cmdline = Str_dup(pinfo[i].p_comm); } FREE(pinfo); kvm_close(kvm_handle); *reference = pt; return treesize; }
/** * Read all processes to initialize the information tree. * @param reference reference of ProcessTree * @param pflags Process engine flags * @return treesize > 0 if succeeded otherwise 0 */ int initprocesstree_sysdep(ProcessTree_T **reference, ProcessEngine_Flags pflags) { size_t size = sizeof(maxslp); static int mib_maxslp[] = {CTL_VM, VM_MAXSLP}; if (sysctl(mib_maxslp, 2, &maxslp, &size, NULL, 0) < 0) { LogError("system statistic error -- vm.maxslp failed\n"); return 0; } int mib_proc2[6] = {CTL_KERN, KERN_PROC2, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), 0}; if (sysctl(mib_proc2, 6, NULL, &size, NULL, 0) == -1) { LogError("system statistic error -- kern.proc2 #1 failed\n"); return 0; } size *= 2; // Add reserve for new processes which were created between calls of sysctl struct kinfo_proc2 *pinfo = CALLOC(1, size); mib_proc2[5] = (int)(size / sizeof(struct kinfo_proc2)); if (sysctl(mib_proc2, 6, pinfo, &size, NULL, 0) == -1) { FREE(pinfo); LogError("system statistic error -- kern.proc2 #2 failed\n"); return 0; } int treesize = (int)(size / sizeof(struct kinfo_proc2)); ProcessTree_T *pt = CALLOC(sizeof(ProcessTree_T), treesize); char buf[_POSIX2_LINE_MAX]; kvm_t *kvm_handle = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, buf); if (! kvm_handle) { FREE(pinfo); FREE(pt); LogError("system statistic error -- kvm_openfiles failed: %s\n", buf); return 0; } StringBuffer_T cmdline = NULL; if (pflags & ProcessEngine_CollectCommandLine) cmdline = StringBuffer_create(64); for (int i = 0; i < treesize; i++) { pt[i].pid = pinfo[i].p_pid; pt[i].ppid = pinfo[i].p_ppid; pt[i].cred.uid = pinfo[i].p_ruid; pt[i].cred.euid = pinfo[i].p_uid; pt[i].cred.gid = pinfo[i].p_rgid; pt[i].threads = pinfo[i].p_nlwps; pt[i].uptime = systeminfo.time / 10. - pinfo[i].p_ustart_sec; pt[i].cpu.time = pinfo[i].p_rtime_sec * 10 + (double)pinfo[i].p_rtime_usec / 100000.; pt[i].memory.usage = (uint64_t)pinfo[i].p_vm_rssize * (uint64_t)pagesize; pt[i].zombie = pinfo[i].p_stat == SZOMB ? true : false; if (pflags & ProcessEngine_CollectCommandLine) { char **args = kvm_getargv2(kvm_handle, &pinfo[i], 0); if (args) { StringBuffer_clear(cmdline); for (int j = 0; args[j]; j++) StringBuffer_append(cmdline, args[j + 1] ? "%s " : "%s", args[j]); if (StringBuffer_length(cmdline)) pt[i].cmdline = Str_dup(StringBuffer_toString(StringBuffer_trim(cmdline))); } if (! pt[i].cmdline || ! *pt[i].cmdline) { FREE(pt[i].cmdline); pt[i].cmdline = Str_dup(pinfo[i].p_comm); } } } if (pflags & ProcessEngine_CollectCommandLine) StringBuffer_free(&cmdline); FREE(pinfo); kvm_close(kvm_handle); *reference = pt; return treesize; }