Commit bf276a09 authored by Hisham Muhammad's avatar Hisham Muhammad
Browse files

Merge pull request #274 from mmcco/master

Cleanup and initial OpenBSD support
parents 5c2b0a6b 6a21d2f3
......@@ -52,8 +52,8 @@ FunctionBar* FunctionBar_new(const char** functions, const char** keys, int* eve
}
if (keys && events) {
this->staticData = false;
this->keys = malloc(sizeof(char*) * 15);
this->events = malloc(sizeof(int) * 15);
this->keys = calloc(15, sizeof(char*));
this->events = calloc(15, sizeof(int));
int i = 0;
while (i < 15 && functions[i]) {
this->keys[i] = strdup(keys[i]);
......
......@@ -63,7 +63,7 @@ int Hashtable_count(Hashtable* this) {
static HashtableItem* HashtableItem_new(unsigned int key, void* value) {
HashtableItem* this;
this = (HashtableItem*) malloc(sizeof(HashtableItem));
this = malloc(sizeof(HashtableItem));
this->key = key;
this->value = value;
this->next = NULL;
......@@ -73,7 +73,7 @@ static HashtableItem* HashtableItem_new(unsigned int key, void* value) {
Hashtable* Hashtable_new(int size, bool owner) {
Hashtable* this;
this = (Hashtable*) malloc(sizeof(Hashtable));
this = malloc(sizeof(Hashtable));
this->items = 0;
this->size = size;
this->buckets = (HashtableItem**) calloc(size, sizeof(HashtableItem*));
......
......@@ -51,6 +51,14 @@ myhtopplatheaders = freebsd/Platform.h freebsd/FreeBSDProcessList.h \
freebsd/FreeBSDProcess.h freebsd/FreeBSDCRT.h freebsd/Battery.h
endif
if HTOP_OPENBSD
myhtopplatsources = openbsd/Platform.c openbsd/OpenBSDProcessList.c \
openbsd/OpenBSDProcess.c openbsd/OpenBSDCRT.c openbsd/Battery.c
myhtopplatheaders = openbsd/Platform.h openbsd/OpenBSDProcessList.h \
openbsd/OpenBSDProcess.h openbsd/OpenBSDCRT.h openbsd/Battery.h
endif
if HTOP_DARWIN
htop_LDFLAGS += -framework IOKit -framework CoreFoundation
myhtopplatsources = darwin/Platform.c darwin/DarwinProcess.c \
......
......@@ -58,7 +58,7 @@ static const char* OpenFilesScreenKeys[] = {"F3", "F4", "F5", "Esc"};
static int OpenFilesScreenEvents[] = {KEY_F(3), KEY_F(4), KEY_F(5), 27};
OpenFilesScreen* OpenFilesScreen_new(Process* process) {
OpenFilesScreen* this = (OpenFilesScreen*) malloc(sizeof(OpenFilesScreen));
OpenFilesScreen* this = malloc(sizeof(OpenFilesScreen));
this->process = process;
FunctionBar* bar = FunctionBar_new(OpenFilesScreenFunctions, OpenFilesScreenKeys, OpenFilesScreenEvents);
this->display = Panel_new(0, 1, COLS, LINES-3, false, Class(ListItem), bar);
......
......@@ -55,13 +55,13 @@ inline int String_eq(const char* s1, const char* s2) {
char** String_split(const char* s, char sep, int* n) {
*n = 0;
const int rate = 10;
char** out = (char**) malloc(sizeof(char*) * rate);
char** out = calloc(rate, sizeof(char*));
int ctr = 0;
int blocks = rate;
char* where;
while ((where = strchr(s, sep)) != NULL) {
int size = where - s;
char* token = (char*) malloc(size + 1);
char* token = malloc(size + 1);
strncpy(token, s, size);
token[size] = '\0';
out[ctr] = token;
......@@ -80,7 +80,7 @@ char** String_split(const char* s, char sep, int* n) {
}
if (s[0] != '\0') {
int size = strlen(s);
char* token = (char*) malloc(size + 1);
char* token = malloc(size + 1);
strncpy(token, s, size + 1);
out[ctr] = token;
ctr++;
......
......@@ -44,7 +44,7 @@ static const char* TraceScreenKeys[] = {"F3", "F4", "F8", "F9", "Esc"};
static int TraceScreenEvents[] = {KEY_F(3), KEY_F(4), KEY_F(8), KEY_F(9), 27};
TraceScreen* TraceScreen_new(Process* process) {
TraceScreen* this = (TraceScreen*) malloc(sizeof(TraceScreen));
TraceScreen* this = malloc(sizeof(TraceScreen));
this->process = process;
FunctionBar* fuBar = FunctionBar_new(TraceScreenFunctions, TraceScreenKeys, TraceScreenEvents);
this->display = Panel_new(0, 1, COLS, LINES-2, false, Class(ListItem), fuBar);
......
......@@ -37,7 +37,7 @@ Vector* Vector_new(ObjectClass* type, bool owner, int size) {
if (size == DEFAULT_SIZE)
size = 10;
this = (Vector*) malloc(sizeof(Vector));
this = malloc(sizeof(Vector));
this->growthRate = size;
this->array = (Object**) calloc(size, sizeof(Object*));
this->arraySize = size;
......
......@@ -33,6 +33,9 @@ case "$target" in
*freebsd*)
my_htop_platform=freebsd
;;
*openbsd*)
my_htop_platform=openbsd
;;
*darwin*)
my_htop_platform=darwin
;;
......@@ -168,6 +171,10 @@ if test "$my_htop_platform" = "freebsd"; then
AC_CHECK_LIB([kvm], [kvm_open], [], [missing_libraries="$missing_libraries libkvm"])
fi
if test "$my_htop_platform" = "openbsd"; then
AC_CHECK_LIB([kvm], [kvm_open], [], [missing_libraries="$missing_libraries libkvm"])
fi
AC_ARG_ENABLE(native_affinity, [AC_HELP_STRING([--enable-native-affinity], [enable native sched_setaffinity and sched_getaffinity for affinity support, disables hwloc])], ,enable_native_affinity="yes")
if test "x$enable_native_affinity" = xyes -a "x$cross_compiling" = xno; then
AC_MSG_CHECKING([for usable sched_setaffinity])
......@@ -211,6 +218,7 @@ AC_DEFINE_UNQUOTED(COPYRIGHT, "(C) 2004-$year Hisham Muhammad", [Copyright messa
# ----------------------------------------------------------------------
AM_CONDITIONAL([HTOP_LINUX], [test "$my_htop_platform" = linux])
AM_CONDITIONAL([HTOP_FREEBSD], [test "$my_htop_platform" = freebsd])
AM_CONDITIONAL([HTOP_OPENBSD], [test "$my_htop_platform" = openbsd])
AM_CONDITIONAL([HTOP_DARWIN], [test "$my_htop_platform" = darwin])
AM_CONDITIONAL([HTOP_UNSUPPORTED], [test "$my_htop_platform" = unsupported])
AC_SUBST(my_htop_platform)
......
......@@ -40,16 +40,14 @@ void ProcessList_getHostInfo(host_basic_info_data_t *p) {
mach_msg_type_number_t info_size = HOST_BASIC_INFO_COUNT;
if(0 != host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)p, &info_size)) {
fprintf(stderr, "Unable to retrieve host info\n");
exit(2);
err(2, "Unable to retrieve host info\n");
}
}
void ProcessList_freeCPULoadInfo(processor_cpu_load_info_t *p) {
if(NULL != p && NULL != *p) {
if(0 != munmap(*p, vm_page_size)) {
fprintf(stderr, "Unable to free old CPU load information\n");
exit(8);
err(8, "Unable to free old CPU load information\n");
}
}
......@@ -62,8 +60,7 @@ unsigned ProcessList_allocateCPULoadInfo(processor_cpu_load_info_t *p) {
// TODO Improving the accuracy of the load counts woule help a lot.
if(0 != host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &cpu_count, (processor_info_array_t *)p, &info_size)) {
fprintf(stderr, "Unable to retrieve CPU info\n");
exit(4);
err(4, "Unable to retrieve CPU info\n");
}
return cpu_count;
......@@ -72,10 +69,8 @@ unsigned ProcessList_allocateCPULoadInfo(processor_cpu_load_info_t *p) {
void ProcessList_getVMStats(vm_statistics64_t p) {
mach_msg_type_number_t info_size = HOST_VM_INFO64_COUNT;
if(0 != host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info_t)p, &info_size)) {
fprintf(stderr, "Unable to retrieve VM statistics\n");
exit(9);
}
if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info_t)p, &info_size) != 0)
err(9, "Unable to retrieve VM statistics\n");
}
struct kinfo_proc *ProcessList_getKInfoProcs(size_t *count) {
......@@ -87,21 +82,15 @@ struct kinfo_proc *ProcessList_getKInfoProcs(size_t *count) {
* process entry or two.
*/
*count = 0;
if(0 > sysctl(mib, 4, NULL, count, NULL, 0)) {
fprintf(stderr, "Unable to get size of kproc_infos");
exit(5);
}
if (sysctl(mib, 4, NULL, count, NULL, 0) < 0)
err(5, "Unable to get size of kproc_infos");
processes = (struct kinfo_proc *)malloc(*count);
if(NULL == processes) {
fprintf(stderr, "Out of memory for kproc_infos\n");
exit(6);
}
processes = malloc(*count);
if (processes == NULL)
errx(6, "Out of memory for kproc_infos");
if(0 > sysctl(mib, 4, processes, count, NULL, 0)) {
fprintf(stderr, "Unable to get kinfo_procs\n");
exit(7);
}
if (sysctl(mib, 4, processes, count, NULL, 0) < 0)
err(7, "Unable to get kinfo_procs");
*count = *count / sizeof(struct kinfo_proc);
......
......@@ -121,7 +121,7 @@ char* FreeBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, in
for (int i = 0; argv[i]; i++) {
len += strlen(argv[i]) + 1;
}
char* comm = malloc(len * sizeof(char));
char* comm = malloc(len);
char* at = comm;
*basenameEnd = 0;
for (int i = 0; argv[i]; i++) {
......
......@@ -108,8 +108,7 @@ static CommandLineSettings parseArguments(int argc, char** argv) {
}
flags.sortKey = ColumnsPanel_fieldNameToIndex(optarg);
if (flags.sortKey == -1) {
fprintf(stderr, "Error: invalid column \"%s\".\n", optarg);
exit(1);
errx(1, stderr, "Error: invalid column \"%s\".\n", optarg);
}
break;
case 'd':
......@@ -117,14 +116,12 @@ static CommandLineSettings parseArguments(int argc, char** argv) {
if (flags.delay < 1) flags.delay = 1;
if (flags.delay > 100) flags.delay = 100;
} else {
fprintf(stderr, "Error: invalid delay value \"%s\".\n", optarg);
exit(1);
errx(1, stderr, "Error: invalid delay value \"%s\".\n", optarg);
}
break;
case 'u':
if (!Action_setUserOnly(optarg, &(flags.userId))) {
fprintf(stderr, "Error: invalid user \"%s\".\n", optarg);
exit(1);
errx(1, stderr, "Error: invalid user \"%s\".\n", optarg);
}
break;
case 'C':
......@@ -135,11 +132,11 @@ static CommandLineSettings parseArguments(int argc, char** argv) {
char* saveptr;
char* pid = strtok_r(argCopy, ",", &saveptr);
if( !flags.pidWhiteList ) {
if(!flags.pidWhiteList) {
flags.pidWhiteList = Hashtable_new(8, false);
}
while( pid ) {
while(pid) {
unsigned int num_pid = atoi(pid);
Hashtable_put(flags.pidWhiteList, num_pid, (void *) 1);
pid = strtok_r(NULL, ",", &saveptr);
......@@ -179,8 +176,7 @@ int main(int argc, char** argv) {
#ifdef HAVE_PROC
if (access(PROCDIR, R_OK) != 0) {
fprintf(stderr, "Error: could not read procfs (compiled to look in %s).\n", PROCDIR);
exit(1);
errx(1, "Error: could not read procfs (compiled to look in %s).\n", PROCDIR);
}
#endif
......
/*
htop - openbsd/Battery.c
(C) 2015 Hisham H. Muhammad
(C) 2015 Michael McConville
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "BatteryMeter.h"
void Battery_getData(double* level, ACPresence* isOnAC) {
// TODO
*level = -1;
*isOnAC = AC_ERROR;
}
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_Battery
#define HEADER_Battery
/*
htop - openbsd/Battery.h
(C) 2015 Hisham H. Muhammad
(C) 2015 Michael McConville
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
void Battery_getData(double* level, ACPresence* isOnAC);
#endif
/*
htop - UnsupportedCRT.c
(C) 2014 Hisham H. Muhammad
(C) 2015 Michael McConville
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "config.h"
#include "CRT.h"
#include <stdio.h>
#include <stdlib.h>
void CRT_handleSIGSEGV(int sgn) {
(void) sgn;
CRT_done();
fprintf(stderr, "\n\nhtop " VERSION " aborting.\n");
fprintf(stderr, "\nUnfortunately, you seem to be using an unsupported platform!");
fprintf(stderr, "\nPlease contact your platform package mantainer!\n\n");
abort();
}
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_UnsupportedCRT
#define HEADER_UnsupportedCRT
/*
htop - UnsupportedCRT.h
(C) 2014 Hisham H. Muhammad
(C) 2015 Michael McConville
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
void CRT_handleSIGSEGV(int sgn);
#endif
/*
htop - OpenBSDProcess.c
(C) 2015 Hisham H. Muhammad
(C) 2015 Michael McConville
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Process.h"
#include "ProcessList.h"
#include "OpenBSDProcess.h"
#include "Platform.h"
#include "CRT.h"
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
/*{
typedef enum OpenBSDProcessFields {
// Add platform-specific fields here, with ids >= 100
LAST_PROCESSFIELD = 100,
} OpenBSDProcessField;
typedef struct OpenBSDProcess_ {
Process super;
} OpenBSDProcess;
#ifndef Process_isKernelThread
#define Process_isKernelThread(_process) (_process->pgrp == 0)
#endif
#ifndef Process_isUserlandThread
#define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
#endif
}*/
ProcessClass OpenBSDProcess_class = {
.super = {
.extends = Class(Process),
.display = Process_display,
.delete = Process_delete,
.compare = OpenBSDProcess_compare
},
.writeField = (Process_WriteField) OpenBSDProcess_writeField,
};
ProcessFieldData Process_fields[] = {
[0] = {
.name = "",
.title = NULL,
.description = NULL,
.flags = 0, },
[PID] = {
.name = "PID",
.title = " PID ",
.description = "Process/thread ID",
.flags = 0, },
[COMM] = {
.name = "Command",
.title = "Command ",
.description = "Command line",
.flags = 0, },
[STATE] = {
.name = "STATE",
.title = "S ",
.description = "Process state (S sleeping, R running, D disk, Z zombie, T traced, W paging)",
.flags = 0, },
[PPID] = {
.name = "PPID",
.title = " PPID ",
.description = "Parent process ID",
.flags = 0, },
[PGRP] = {
.name = "PGRP",
.title = " PGRP ",
.description = "Process group ID",
.flags = 0, },
[SESSION] = {
.name = "SESSION",
.title = " SESN ",
.description = "Process's session ID",
.flags = 0, },
[TTY_NR] = {
.name = "TTY_NR",
.title = " TTY ",
.description = "Controlling terminal",
.flags = 0, },
[TPGID] = {
.name = "TPGID",
.title = " TPGID ",
.description = "Process ID of the fg process group of the controlling terminal",
.flags = 0, },
[MINFLT] = {
.name = "MINFLT",
.title = " MINFLT ",
.description = "Number of minor faults which have not required loading a memory page from disk",
.flags = 0, },
[MAJFLT] = {
.name = "MAJFLT",
.title = " MAJFLT ",
.description = "Number of major faults which have required loading a memory page from disk",
.flags = 0, },
[PRIORITY] = {
.name = "PRIORITY",
.title = "PRI ",
.description = "Kernel's internal priority for the process",
.flags = 0, },
[NICE] = {
.name = "NICE",
.title = " NI ",
.description = "Nice value (the higher the value, the more it lets other processes take priority)",
.flags = 0, },
[STARTTIME] = {
.name = "STARTTIME",
.title = "START ",
.description = "Time the process was started",
.flags = 0, },
[PROCESSOR] = {
.name = "PROCESSOR",
.title = "CPU ",
.description = "Id of the CPU the process last executed on",
.flags = 0, },
[M_SIZE] = {
.name = "M_SIZE",
.title = " VIRT ",
.description = "Total program size in virtual memory",
.flags = 0, },
[M_RESIDENT] = {
.name = "M_RESIDENT",
.title = " RES ",
.description = "Resident set size, size of the text and data sections, plus stack usage",
.flags = 0, },
[ST_UID] = {
.name = "ST_UID",
.title = " UID ",
.description = "User ID of the process owner",
.flags = 0, },
[PERCENT_CPU] = {
.name = "PERCENT_CPU",
.title = "CPU% ",
.description = "Percentage of the CPU time the process used in the last sampling",
.flags = 0, },
[PERCENT_MEM] = {
.name = "PERCENT_MEM",
.title = "MEM% ",
.description = "Percentage of the memory the process is using, based on resident memory size",
.flags = 0, },
[USER] = {
.name = "USER",
.title = "USER ",
.description = "Username of the process owner (or user ID if name cannot be determined)",
.flags = 0, },
[TIME] = {
.name = "TIME",
.title = " TIME+ ",
.description = "Total time the process has spent in user and system time",
.flags = 0, },
[NLWP] = {
.name = "NLWP",
.title = "NLWP ",
.description = "Number of threads in the process",
.flags = 0, },
[TGID] = {
.name = "TGID",
.title = " TGID ",
.description = "Thread group ID (i.e. process ID)",
.flags = 0, },
[LAST_PROCESSFIELD] = {
.name = "*** report bug! ***",
.title = NULL,
.description = NULL,
.flags = 0, },
};
ProcessPidColumn Process_pidColumns[] = {
{ .id = PID, .label = "PID" },
{ .id = PPID, .label = "PPID" },
{ .id = TPGID, .label = "TPGID" },
{ .id = TGID, .label = "TGID" },
{ .id = PGRP, .label = "PGRP" },
{ .id = SESSION, .label = "SESN" },
{ .id = 0, .label = NULL },
};
OpenBSDProcess* OpenBSDProcess_new(Settings* settings) {
OpenBSDProcess* this = calloc(sizeof(OpenBSDProcess), 1);
Object_setClass(this, Class(OpenBSDProcess));
Process_init(&this->super, settings);
return this;
}
void Process_delete(Object* cast) {
OpenBSDProcess* this = (OpenBSDProcess*) cast;
Process_done((Process*)cast);
free(this);
}
void OpenBSDProcess_writeField(Process* this, RichString* str, ProcessField field) {
//OpenBSDProcess* fp = (OpenBSDProcess*) this;
char buffer[256]; buffer[255] = '\0';
int attr = CRT_colors[DEFAULT_COLOR];
//int n = sizeof(buffer) - 1;
switch (field) {
// add OpenBSD-specific fields here
default:
Process_writeField(this, str, field);
return;
}
RichString_append(str, attr, buffer);
}
long OpenBSDProcess_compare(const void* v1, const void* v2) {
OpenBSDProcess *p1, *p2;
Settings *settings = ((Process*)v1)->settings;
if (settings->direction == 1) {
p1 = (OpenBSDProcess*)v1;
p2 = (OpenBSDProcess*)v2;
} else {
p2 = (OpenBSDProcess*)v1;
p1 = (OpenBSDProcess*)v2;
}
switch (settings->sortKey) {
// add OpenBSD-specific fields here
default:
return Process_compare(v1, v2);
}
}
bool Process_isThread(Process* this) {
return (Process_isKernelThread(this));
}
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_OpenBSDProcess
#define HEADER_OpenBSDProcess
/*
htop - OpenBSDProcess.h
(C) 2015 Hisham H. Muhammad
(C) 2015 Michael McConville
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
typedef enum OpenBSDProcessFields {
// Add platform-specific fields here, with ids >= 100
LAST_PROCESSFIELD = 100,
} OpenBSDProcessField;
typedef struct OpenBSDProcess_ {
Process super;
} OpenBSDProcess;
#ifndef Process_isKernelThread
#define Process_isKernelThread(_process) (_process->pgrp == 0)
#endif
#ifndef Process_isUserlandThread
#define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
#endif
extern ProcessClass OpenBSDProcess_class;
extern ProcessFieldData Process_fields[];
extern ProcessPidColumn Process_pidColumns[];
OpenBSDProcess* OpenBSDProcess_new(Settings* settings);
void Process_delete(Object* cast);
void OpenBSDProcess_writeField(Process* this, RichString* str, ProcessField field);
long OpenBSDProcess_compare(const void* v1, const void* v2);
bool Process_isThread(Process* this);
#endif
/*
htop - OpenBSDProcessList.c
(C) 2014 Hisham H. Muhammad
(C) 2015 Michael McConville
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "ProcessList.h"
#include "OpenBSDProcessList.h"
#include "OpenBSDProcess.h"
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <err.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <fcntl.h>
#include <string.h>
#include <sys/resource.h>
/*{
#include <kvm.h>
typedef struct CPUData_ {
unsigned long long int totalTime;
unsigned long long int totalPeriod;
} CPUData;
typedef struct OpenBSDProcessList_ {
ProcessList super;
kvm_t* kd;
CPUData* cpus;
} OpenBSDProcessList;
}*/
static int pageSizeKb;
static long fscale;
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, uid_t userId) {
int mib[] = { CTL_HW, HW_NCPU };
int fmib[] = { CTL_KERN, KERN_FSCALE };
int i;
OpenBSDProcessList* fpl = calloc(1, sizeof(OpenBSDProcessList));
ProcessList* pl = (ProcessList*) fpl;
size_t size = sizeof(pl->cpuCount);
ProcessList_init(pl, Class(OpenBSDProcess), usersTable, pidWhiteList, userId);
pl->cpuCount = 1; // default to 1 on sysctl() error
(void)sysctl(mib, 2, &pl->cpuCount, &size, NULL, 0);
fpl->cpus = realloc(fpl->cpus, pl->cpuCount * sizeof(CPUData));
size = sizeof(fscale);
if (sysctl(fmib, 2, &fscale, &size, NULL, 0) < 0)
err(1, "fscale sysctl call failed");
for (i = 0; i < pl->cpuCount; i++) {
fpl->cpus[i].totalTime = 1;
fpl->cpus[i].totalPeriod = 1;
}
pageSizeKb = PAGE_SIZE_KB;
// XXX: last arg should eventually be an errbuf
fpl->kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
assert(fpl->kd);
return pl;
}
void ProcessList_delete(ProcessList* this) {
const OpenBSDProcessList* fpl = (OpenBSDProcessList*) this;
if (fpl->kd) kvm_close(fpl->kd);
ProcessList_done(this);
free(this);
}
static inline void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
static int uvmexp_mib[] = {CTL_VM, VM_UVMEXP};
struct uvmexp uvmexp;
size_t size = sizeof(uvmexp);
if (sysctl(uvmexp_mib, 2, &uvmexp, &size, NULL, 0) < 0) {
err(1, "uvmexp sysctl call failed");
}
//kb_pagesize = uvmexp.pagesize / 1024;
pl->usedMem = uvmexp.active * pageSizeKb;
pl->totalMem = uvmexp.npages * pageSizeKb;
/*
const OpenBSDProcessList* fpl = (OpenBSDProcessList*) pl;
size_t len = sizeof(pl->totalMem);
sysctl(MIB_hw_physmem, 2, &(pl->totalMem), &len, NULL, 0);
pl->totalMem /= 1024;
sysctl(MIB_vm_stats_vm_v_wire_count, 4, &(pl->usedMem), &len, NULL, 0);
pl->usedMem *= pageSizeKb;
pl->freeMem = pl->totalMem - pl->usedMem;
sysctl(MIB_vm_stats_vm_v_cache_count, 4, &(pl->cachedMem), &len, NULL, 0);
pl->cachedMem *= pageSizeKb;
struct kvm_swap swap[16];
int nswap = kvm_getswapinfo(fpl->kd, swap, sizeof(swap)/sizeof(swap[0]), 0);
pl->totalSwap = 0;
pl->usedSwap = 0;
for (int i = 0; i < nswap; i++) {
pl->totalSwap += swap[i].ksw_total;
pl->usedSwap += swap[i].ksw_used;
}
pl->totalSwap *= pageSizeKb;
pl->usedSwap *= pageSizeKb;
pl->sharedMem = 0; // currently unused
pl->buffersMem = 0; // not exposed to userspace
*/
}
char *OpenBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, int* basenameEnd) {
char *str, *buf, **argv;
size_t cpsz;
size_t len = 500;
argv = kvm_getargv(kd, kproc, 500);
if (argv == NULL)
err(1, "kvm call failed");
str = buf = malloc(len+1);
if (str == NULL)
err(1, "out of memory");
while (*argv != NULL) {
cpsz = MIN(len, strlen(*argv));
strncpy(buf, *argv, cpsz);
buf += cpsz;
len -= cpsz;
argv++;
if (len > 0) {
*buf = ' ';
buf++;
len--;
}
}
*buf = '\0';
return str;
}
/*
* Taken from OpenBSD's ps(1).
*/
double getpcpu(const struct kinfo_proc *kp) {
if (fscale == 0)
return (0.0);
#define fxtofl(fixpt) ((double)(fixpt) / fscale)
return (100.0 * fxtofl(kp->p_pctcpu));
}
void ProcessList_goThroughEntries(ProcessList* this) {
OpenBSDProcessList* fpl = (OpenBSDProcessList*) this;
Settings* settings = this->settings;
bool hideKernelThreads = settings->hideKernelThreads;
bool hideUserlandThreads = settings->hideUserlandThreads;
struct kinfo_proc* kproc;
bool preExisting;
Process* proc;
OpenBSDProcess* fp;
int count = 0;
int i;
OpenBSDProcessList_scanMemoryInfo(this);
// use KERN_PROC_KTHREAD to also include kernel threads
struct kinfo_proc* kprocs = kvm_getprocs(fpl->kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &count);
//struct kinfo_proc* kprocs = getprocs(KERN_PROC_ALL, 0, &count);
for (i = 0; i < count; i++) {
kproc = &kprocs[i];
preExisting = false;
proc = ProcessList_getProcess(this, kproc->p_pid, &preExisting, (Process_New) OpenBSDProcess_new);
fp = (OpenBSDProcess*) proc;
proc->show = ! ((hideKernelThreads && Process_isKernelThread(proc))
|| (hideUserlandThreads && Process_isUserlandThread(proc)));
if (!preExisting) {
proc->ppid = kproc->p_ppid;
proc->tpgid = kproc->p_tpgid;
proc->tgid = kproc->p_pid;
proc->session = kproc->p_sid;
proc->tty_nr = kproc->p_tdev;
proc->pgrp = kproc->p__pgid;
proc->st_uid = kproc->p_uid;
proc->starttime_ctime = kproc->p_ustart_sec;
proc->user = UsersTable_getRef(this->usersTable, proc->st_uid);
ProcessList_add((ProcessList*)this, proc);
proc->comm = OpenBSDProcessList_readProcessName(fpl->kd, kproc, &proc->basenameOffset);
} else {
if (settings->updateProcessNames) {
free(proc->comm);
proc->comm = OpenBSDProcessList_readProcessName(fpl->kd, kproc, &proc->basenameOffset);
}
}
proc->m_size = kproc->p_vm_dsize;
proc->m_resident = kproc->p_vm_rssize;
proc->percent_mem = (proc->m_resident * PAGE_SIZE_KB) / (double)(this->totalMem) * 100.0;
proc->percent_cpu = MAX(MIN(getpcpu(kproc), this->cpuCount*100.0), 0.0);
//proc->nlwp = kproc->p_numthreads;
//proc->time = kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 10);
proc->nice = kproc->p_nice - 20;
proc->time = kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 1000000);
proc->time *= 100;
proc->priority = kproc->p_priority - PZERO;
switch (kproc->p_stat) {
case SIDL: proc->state = 'I'; break;
case SRUN: proc->state = 'R'; break;
case SSLEEP: proc->state = 'S'; break;
case SSTOP: proc->state = 'T'; break;
case SZOMB: proc->state = 'Z'; break;
case SDEAD: proc->state = 'D'; break;
case SONPROC: proc->state = 'P'; break;
default: proc->state = '?';
}
if (Process_isKernelThread(proc)) {
this->kernelThreads++;
}
this->totalTasks++;
// SRUN ('R') means runnable, not running
if (proc->state == 'P') {
this->runningTasks++;
}
proc->updated = true;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment