aboutsummaryrefslogtreecommitdiffstats
path: root/freebsd
diff options
context:
space:
mode:
authorDaniel Lange <DLange@git.local>2020-12-07 10:26:01 +0100
committerDaniel Lange <DLange@git.local>2020-12-07 10:26:01 +0100
commit65357c8c46154de4e4eca14075bfe5523bb5fc14 (patch)
tree8f430ee5a0d5de377c4e7c94e47842a27c70d7e8 /freebsd
parentf80394a20254938142011855f2954b3f63fe5909 (diff)
downloaddebian_htop-65357c8c46154de4e4eca14075bfe5523bb5fc14.tar.gz
debian_htop-65357c8c46154de4e4eca14075bfe5523bb5fc14.tar.bz2
debian_htop-65357c8c46154de4e4eca14075bfe5523bb5fc14.zip
New upstream version 3.0.3upstream/3.0.3
Diffstat (limited to 'freebsd')
-rw-r--r--freebsd/Battery.c25
-rw-r--r--freebsd/Battery.h12
-rw-r--r--freebsd/FreeBSDCRT.c20
-rw-r--r--freebsd/FreeBSDCRT.h12
-rw-r--r--freebsd/FreeBSDProcess.c93
-rw-r--r--freebsd/FreeBSDProcess.h32
-rw-r--r--freebsd/FreeBSDProcessList.c312
-rw-r--r--freebsd/FreeBSDProcessList.h32
-rw-r--r--freebsd/Platform.c244
-rw-r--r--freebsd/Platform.h37
10 files changed, 524 insertions, 295 deletions
diff --git a/freebsd/Battery.c b/freebsd/Battery.c
deleted file mode 100644
index b8c5e31..0000000
--- a/freebsd/Battery.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-htop - freebsd/Battery.c
-(C) 2015 Hisham H. Muhammad
-Released under the GNU GPL, see the COPYING file
-in the source distribution for its full text.
-*/
-
-#include "BatteryMeter.h"
-#include <sys/sysctl.h>
-
-void Battery_getData(double* level, ACPresence* isOnAC) {
- int life;
- size_t life_len = sizeof(life);
- if (sysctlbyname("hw.acpi.battery.life", &life, &life_len, NULL, 0) == -1)
- *level = -1;
- else
- *level = life;
-
- int acline;
- size_t acline_len = sizeof(acline);
- if (sysctlbyname("hw.acpi.acline", &acline, &acline_len, NULL, 0) == -1)
- *isOnAC = AC_ERROR;
- else
- *isOnAC = acline == 0 ? AC_ABSENT : AC_PRESENT;
-}
diff --git a/freebsd/Battery.h b/freebsd/Battery.h
deleted file mode 100644
index 6987d78..0000000
--- a/freebsd/Battery.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef HEADER_Battery
-#define HEADER_Battery
-/*
-htop - freebsd/Battery.h
-(C) 2015 Hisham H. Muhammad
-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
diff --git a/freebsd/FreeBSDCRT.c b/freebsd/FreeBSDCRT.c
deleted file mode 100644
index 49cc5d0..0000000
--- a/freebsd/FreeBSDCRT.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-htop - UnsupportedCRT.c
-(C) 2014 Hisham H. Muhammad
-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 maintainer!\n\n");
- abort();
-}
diff --git a/freebsd/FreeBSDCRT.h b/freebsd/FreeBSDCRT.h
deleted file mode 100644
index eb88fcc..0000000
--- a/freebsd/FreeBSDCRT.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef HEADER_FreeBSDCRT
-#define HEADER_FreeBSDCRT
-/*
-htop - UnsupportedCRT.h
-(C) 2014 Hisham H. Muhammad
-Released under the GNU GPL, see the COPYING file
-in the source distribution for its full text.
-*/
-
-void CRT_handleSIGSEGV(int sgn);
-
-#endif
diff --git a/freebsd/FreeBSDProcess.c b/freebsd/FreeBSDProcess.c
index 33dc751..d6d67b7 100644
--- a/freebsd/FreeBSDProcess.c
+++ b/freebsd/FreeBSDProcess.c
@@ -1,31 +1,22 @@
/*
htop - FreeBSDProcess.c
(C) 2015 Hisham H. Muhammad
-Released under the GNU GPL, see the COPYING file
+Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
-#include "Process.h"
-#include "ProcessList.h"
#include "FreeBSDProcess.h"
-#include "Platform.h"
-#include "CRT.h"
#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/syscall.h>
+#include "CRT.h"
+#include "Macros.h"
+#include "Process.h"
+#include "RichString.h"
+#include "XUtils.h"
-ProcessClass FreeBSDProcess_class = {
- .super = {
- .extends = Class(Process),
- .display = Process_display,
- .delete = Process_delete,
- .compare = FreeBSDProcess_compare
- },
- .writeField = (Process_WriteField) FreeBSDProcess_writeField,
-};
+
+const char* const nodevStr = "nodev";
ProcessFieldData Process_fields[] = {
[0] = { .name = "", .title = NULL, .description = NULL, .flags = 0, },
@@ -35,7 +26,7 @@ ProcessFieldData Process_fields[] = {
[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 = " SID ", .description = "Process's session ID", .flags = 0, },
- [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = 0, },
+ [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = PROCESS_FLAG_FREEBSD_TTY, },
[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, },
@@ -44,10 +35,11 @@ ProcessFieldData Process_fields[] = {
[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_VIRT] = { .name = "M_VIRT", .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_NORM_CPU] = { .name = "PERCENT_NORM_CPU", .title = "NCPU%", .description = "Normalized percentage of the CPU time the process used in the last sampling (normalized by cpu count)", .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, },
@@ -69,11 +61,11 @@ ProcessPidColumn Process_pidColumns[] = {
{ .id = 0, .label = NULL },
};
-FreeBSDProcess* FreeBSDProcess_new(Settings* settings) {
+Process* FreeBSDProcess_new(const Settings* settings) {
FreeBSDProcess* this = xCalloc(1, sizeof(FreeBSDProcess));
Object_setClass(this, Class(FreeBSDProcess));
Process_init(&this->super, settings);
- return this;
+ return &this->super;
}
void Process_delete(Object* cast) {
@@ -83,15 +75,15 @@ void Process_delete(Object* cast) {
free(this);
}
-void FreeBSDProcess_writeField(Process* this, RichString* str, ProcessField field) {
- FreeBSDProcess* fp = (FreeBSDProcess*) this;
+static void FreeBSDProcess_writeField(const Process* this, RichString* str, ProcessField field) {
+ const FreeBSDProcess* fp = (const FreeBSDProcess*) this;
char buffer[256]; buffer[255] = '\0';
int attr = CRT_colors[DEFAULT_COLOR];
int n = sizeof(buffer) - 1;
switch ((int) field) {
// add FreeBSD-specific fields here
case JID: xSnprintf(buffer, n, Process_pidFormat, fp->jid); break;
- case JAIL:{
+ case JAIL: {
xSnprintf(buffer, n, "%-11s ", fp->jname);
if (buffer[11] != '\0') {
buffer[11] = ' ';
@@ -99,6 +91,16 @@ void FreeBSDProcess_writeField(Process* this, RichString* str, ProcessField fiel
}
break;
}
+ case TTY_NR:
+ if (fp->ttyPath) {
+ if (fp->ttyPath == nodevStr)
+ attr = CRT_colors[PROCESS_SHADOW];
+ xSnprintf(buffer, n, "%-8s", fp->ttyPath);
+ } else {
+ attr = CRT_colors[PROCESS_SHADOW];
+ xSnprintf(buffer, n, "? ");
+ }
+ break;
default:
Process_writeField(this, str, field);
return;
@@ -106,32 +108,47 @@ void FreeBSDProcess_writeField(Process* this, RichString* str, ProcessField fiel
RichString_append(str, attr, buffer);
}
-long FreeBSDProcess_compare(const void* v1, const void* v2) {
- FreeBSDProcess *p1, *p2;
- Settings *settings = ((Process*)v1)->settings;
+static long FreeBSDProcess_compare(const void* v1, const void* v2) {
+ const FreeBSDProcess *p1, *p2;
+ const Settings *settings = ((const Process*)v1)->settings;
+
if (settings->direction == 1) {
- p1 = (FreeBSDProcess*)v1;
- p2 = (FreeBSDProcess*)v2;
+ p1 = (const FreeBSDProcess*)v1;
+ p2 = (const FreeBSDProcess*)v2;
} else {
- p2 = (FreeBSDProcess*)v1;
- p1 = (FreeBSDProcess*)v2;
+ p2 = (const FreeBSDProcess*)v1;
+ p1 = (const FreeBSDProcess*)v2;
}
+
switch ((int) settings->sortKey) {
// add FreeBSD-specific fields here
case JID:
- return (p1->jid - p2->jid);
+ return SPACESHIP_NUMBER(p1->jid, p2->jid);
case JAIL:
- return strcmp(p1->jname ? p1->jname : "", p2->jname ? p2->jname : "");
+ return SPACESHIP_NULLSTR(p1->jname, p2->jname);
+ case TTY_NR:
+ return SPACESHIP_NULLSTR(p1->ttyPath, p2->ttyPath);
default:
return Process_compare(v1, v2);
}
}
-bool Process_isThread(Process* this) {
- FreeBSDProcess* fp = (FreeBSDProcess*) this;
+bool Process_isThread(const Process* this) {
+ const FreeBSDProcess* fp = (const FreeBSDProcess*) this;
- if (fp->kernel == 1 )
+ if (fp->kernel == 1 ) {
return 1;
- else
- return (Process_isUserlandThread(this));
+ } else {
+ return Process_isUserlandThread(this);
+ }
}
+
+const ProcessClass FreeBSDProcess_class = {
+ .super = {
+ .extends = Class(Process),
+ .display = Process_display,
+ .delete = Process_delete,
+ .compare = FreeBSDProcess_compare
+ },
+ .writeField = FreeBSDProcess_writeField,
+};
diff --git a/freebsd/FreeBSDProcess.h b/freebsd/FreeBSDProcess.h
index 897c532..8911976 100644
--- a/freebsd/FreeBSDProcess.h
+++ b/freebsd/FreeBSDProcess.h
@@ -3,10 +3,21 @@
/*
htop - FreeBSDProcess.h
(C) 2015 Hisham H. Muhammad
-Released under the GNU GPL, see the COPYING file
+Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
+#include <stdbool.h>
+
+#include "Object.h"
+#include "Process.h"
+#include "Settings.h"
+
+
+#define PROCESS_FLAG_FREEBSD_TTY 0x0100
+
+extern const char* const nodevStr;
+
typedef enum FreeBSDProcessFields_ {
// Add platform-specific fields here, with ids >= 100
JID = 100,
@@ -19,26 +30,27 @@ typedef struct FreeBSDProcess_ {
int kernel;
int jid;
char* jname;
+ const char* ttyPath;
} FreeBSDProcess;
-#define Process_isKernelThread(_process) (_process->kernel == 1)
+static inline bool Process_isKernelThread(const Process* this) {
+ return ((const FreeBSDProcess*)this)->kernel == 1;
+}
-#define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
+static inline bool Process_isUserlandThread(const Process* this) {
+ return this->pid != this->tgid;
+}
-extern ProcessClass FreeBSDProcess_class;
+extern const ProcessClass FreeBSDProcess_class;
extern ProcessFieldData Process_fields[];
extern ProcessPidColumn Process_pidColumns[];
-FreeBSDProcess* FreeBSDProcess_new(Settings* settings);
+Process* FreeBSDProcess_new(const Settings* settings);
void Process_delete(Object* cast);
-void FreeBSDProcess_writeField(Process* this, RichString* str, ProcessField field);
-
-long FreeBSDProcess_compare(const void* v1, const void* v2);
-
-bool Process_isThread(Process* this);
+bool Process_isThread(const Process* this);
#endif
diff --git a/freebsd/FreeBSDProcessList.c b/freebsd/FreeBSDProcessList.c
index 6318d42..9aaab5d 100644
--- a/freebsd/FreeBSDProcessList.c
+++ b/freebsd/FreeBSDProcessList.c
@@ -1,26 +1,44 @@
/*
htop - FreeBSDProcessList.c
(C) 2014 Hisham H. Muhammad
-Released under the GNU GPL, see the COPYING file
+Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
-#include "ProcessList.h"
#include "FreeBSDProcessList.h"
-#include "FreeBSDProcess.h"
-#include "zfs/ZfsArcStats.h"
-#include "zfs/openzfs_sysctl.h"
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/sysctl.h>
-#include <sys/user.h>
+#include <assert.h>
+#include <dirent.h>
#include <err.h>
-#include <fcntl.h>
#include <limits.h>
+#include <stdlib.h>
#include <string.h>
-#include <time.h>
+#include <sys/_iovec.h>
+#include <sys/dirent.h>
+#include <sys/errno.h>
+#include <sys/param.h> // needs to be included before <sys/jail.h> for MAXPATHLEN
+#include <sys/jail.h>
+#include <sys/priority.h>
+#include <sys/proc.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+#include "CRT.h"
+#include "Compat.h"
+#include "FreeBSDProcess.h"
+#include "Macros.h"
+#include "Object.h"
+#include "Process.h"
+#include "ProcessList.h"
+#include "Settings.h"
+#include "XUtils.h"
+#include "zfs/ZfsArcStats.h"
+#include "zfs/openzfs_sysctl.h"
+
char jail_errmsg[JAIL_ERRMSGLEN];
@@ -55,8 +73,8 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
len = sizeof(pageSize);
if (sysctlbyname("vm.stats.vm.v_page_size", &pageSize, &len, NULL, 0) == -1) {
- pageSize = PAGE_SIZE;
- pageSizeKb = PAGE_SIZE_KB;
+ pageSize = CRT_pageSize;
+ pageSizeKb = CRT_pageSize;
} else {
pageSizeKb = pageSize / ONE_K;
}
@@ -88,7 +106,9 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
if (smp) {
int err = sysctlbyname("kern.smp.cpus", &cpus, &len, NULL, 0);
- if (err) cpus = 1;
+ if (err) {
+ cpus = 1;
+ }
} else {
cpus = 1;
}
@@ -114,10 +134,10 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
pl->cpuCount = MAXIMUM(cpus, 1);
if (cpus == 1 ) {
- fpl->cpus = xRealloc(fpl->cpus, sizeof(CPUData));
+ fpl->cpus = xRealloc(fpl->cpus, sizeof(CPUData));
} else {
- // on smp we need CPUs + 1 to store averages too (as kernel kindly provides that as well)
- fpl->cpus = xRealloc(fpl->cpus, (pl->cpuCount + 1) * sizeof(CPUData));
+ // on smp we need CPUs + 1 to store averages too (as kernel kindly provides that as well)
+ fpl->cpus = xRealloc(fpl->cpus, (pl->cpuCount + 1) * sizeof(CPUData));
}
@@ -132,12 +152,19 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
errx(1, "kvm_open: %s", errbuf);
}
+ fpl->ttys = Hashtable_new(20, true);
+
return pl;
}
void ProcessList_delete(ProcessList* this) {
const FreeBSDProcessList* fpl = (FreeBSDProcessList*) this;
- if (fpl->kd) kvm_close(fpl->kd);
+
+ Hashtable_delete(fpl->ttys);
+
+ if (fpl->kd) {
+ kvm_close(fpl->kd);
+ }
free(fpl->cp_time_o);
free(fpl->cp_time_n);
@@ -160,8 +187,8 @@ static inline void FreeBSDProcessList_scanCPUTime(ProcessList* pl) {
size_t sizeof_cp_time_array;
- unsigned long *cp_time_n; // old clicks state
- unsigned long *cp_time_o; // current clicks state
+ unsigned long* cp_time_n; // old clicks state
+ unsigned long* cp_time_o; // current clicks state
unsigned long cp_time_d[CPUSTATES];
double cp_time_p[CPUSTATES];
@@ -172,12 +199,12 @@ static inline void FreeBSDProcessList_scanCPUTime(ProcessList* pl) {
// get rest of CPUs
if (cpus > 1) {
- // on smp systems FreeBSD kernel concats all CPU states into one long array in
- // kern.cp_times sysctl OID
- // we store averages in fpl->cpus[0], and actual cores after that
- maxcpu = cpus + 1;
- sizeof_cp_time_array = cpus * sizeof(unsigned long) * CPUSTATES;
- sysctl(MIB_kern_cp_times, 2, fpl->cp_times_n, &sizeof_cp_time_array, NULL, 0);
+ // on smp systems FreeBSD kernel concats all CPU states into one long array in
+ // kern.cp_times sysctl OID
+ // we store averages in fpl->cpus[0], and actual cores after that
+ maxcpu = cpus + 1;
+ sizeof_cp_time_array = cpus * sizeof(unsigned long) * CPUSTATES;
+ sysctl(MIB_kern_cp_times, 2, fpl->cp_times_n, &sizeof_cp_time_array, NULL, 0);
}
for (int i = 0; i < maxcpu; i++) {
@@ -187,14 +214,14 @@ static inline void FreeBSDProcessList_scanCPUTime(ProcessList* pl) {
cp_time_o = fpl->cp_time_o;
} else {
if (i == 0 ) {
- // average
- cp_time_n = fpl->cp_time_n;
- cp_time_o = fpl->cp_time_o;
+ // average
+ cp_time_n = fpl->cp_time_n;
+ cp_time_o = fpl->cp_time_o;
} else {
- // specific smp cores
- cp_times_offset = i - 1;
- cp_time_n = fpl->cp_times_n + (cp_times_offset * CPUSTATES);
- cp_time_o = fpl->cp_times_o + (cp_times_offset * CPUSTATES);
+ // specific smp cores
+ cp_times_offset = i - 1;
+ cp_time_n = fpl->cp_times_n + (cp_times_offset * CPUSTATES);
+ cp_time_o = fpl->cp_times_o + (cp_times_offset * CPUSTATES);
}
}
@@ -203,19 +230,21 @@ static inline void FreeBSDProcessList_scanCPUTime(ProcessList* pl) {
unsigned long long total_n = 0;
unsigned long long total_d = 0;
for (int s = 0; s < CPUSTATES; s++) {
- cp_time_d[s] = cp_time_n[s] - cp_time_o[s];
- total_o += cp_time_o[s];
- total_n += cp_time_n[s];
+ cp_time_d[s] = cp_time_n[s] - cp_time_o[s];
+ total_o += cp_time_o[s];
+ total_n += cp_time_n[s];
}
// totals
total_d = total_n - total_o;
- if (total_d < 1 ) total_d = 1;
+ if (total_d < 1 ) {
+ total_d = 1;
+ }
// save current state as old and calc percentages
for (int s = 0; s < CPUSTATES; ++s) {
- cp_time_o[s] = cp_time_n[s];
- cp_time_p[s] = ((double)cp_time_d[s]) / ((double)total_d) * 100;
+ cp_time_o[s] = cp_time_n[s];
+ cp_time_p[s] = ((double)cp_time_d[s]) / ((double)total_d) * 100;
}
CPUData* cpuData = &(fpl->cpus[i]);
@@ -247,7 +276,6 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) {
u_long totalMem;
u_int memActive, memWire, cachedMem;
long buffersMem;
- uint64_t memZfsArc;
size_t len;
//disabled for now, as it is always smaller than phycal amount of memory...
@@ -286,14 +314,8 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) {
pl->usedMem = fpl->memActive + fpl->memWire;
- //currently unused, same as with arc, custom meter perhaps
- //sysctl(MIB_vm_stats_vm_v_inactive_count, 4, &(fpl->memInactive), &len, NULL, 0);
- //sysctl(MIB_vm_stats_vm_v_free_count, 4, &(fpl->memFree), &len, NULL, 0);
- //pl->freeMem = fpl->memInactive + fpl->memFree;
- //pl->freeMem *= pageSizeKb;
-
struct kvm_swap swap[16];
- int nswap = kvm_getswapinfo(fpl->kd, swap, sizeof(swap)/sizeof(swap[0]), 0);
+ int nswap = kvm_getswapinfo(fpl->kd, swap, ARRAYSIZE(swap), 0);
pl->totalSwap = 0;
pl->usedSwap = 0;
for (int i = 0; i < nswap; i++) {
@@ -302,11 +324,73 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) {
}
pl->totalSwap *= pageSizeKb;
pl->usedSwap *= pageSizeKb;
+}
+
+static void FreeBSDProcessList_scanTTYs(ProcessList* pl) {
+ FreeBSDProcessList* fpl = (FreeBSDProcessList*) pl;
+
+ // scan /dev/tty*
+ {
+ DIR* dirPtr = opendir("/dev");
+ if (!dirPtr)
+ return;
- pl->sharedMem = 0; // currently unused
+ int dirFd = dirfd(dirPtr);
+ if (dirFd < 0)
+ goto err1;
+
+ const struct dirent* entry;
+ while ((entry = readdir(dirPtr))) {
+ if (!String_startsWith(entry->d_name, "tty"))
+ continue;
+
+ struct stat info;
+ if (Compat_fstatat(dirFd, "/dev", entry->d_name, &info, 0) < 0)
+ continue;
+
+ if (!S_ISCHR(info.st_mode))
+ continue;
+
+ if (!Hashtable_get(fpl->ttys, info.st_rdev))
+ Hashtable_put(fpl->ttys, info.st_rdev, xStrdup(entry->d_name));
+ }
+
+err1:
+ closedir(dirPtr);
+ }
+
+ // scan /dev/pts/*
+ {
+ DIR* dirPtr = opendir("/dev/pts");
+ if (!dirPtr)
+ return;
+
+ int dirFd = dirfd(dirPtr);
+ if (dirFd < 0)
+ goto err2;
+
+ const struct dirent* entry;
+ while ((entry = readdir(dirPtr))) {
+ struct stat info;
+ if (Compat_fstatat(dirFd, "/dev/pts", entry->d_name, &info, 0) < 0)
+ continue;
+
+ if (!S_ISCHR(info.st_mode))
+ continue;
+
+ if (!Hashtable_get(fpl->ttys, info.st_rdev)) {
+ char* path;
+ xAsprintf(&path, "pts/%s", entry->d_name);
+ Hashtable_put(fpl->ttys, info.st_rdev, path);
+ }
+ }
+
+err2:
+ closedir(dirPtr);
+ }
}
-char* FreeBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, int* basenameEnd) {
+static char* FreeBSDProcessList_readProcessName(kvm_t* kd, const struct kinfo_proc* kproc, int* basenameEnd) {
char** argv = kvm_getargv(kd, kproc, 0);
if (!argv) {
return xStrdup(kproc->ki_comm);
@@ -331,109 +415,109 @@ char* FreeBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, in
return comm;
}
-char* FreeBSDProcessList_readJailName(struct kinfo_proc* kproc) {
- int jid;
- struct iovec jiov[6];
- char* jname;
+static char* FreeBSDProcessList_readJailName(const struct kinfo_proc* kproc) {
+ char* jname = NULL;
char jnamebuf[MAXHOSTNAMELEN];
- if (kproc->ki_jid != 0 ){
+ if (kproc->ki_jid != 0 ) {
+ struct iovec jiov[6];
+
memset(jnamebuf, 0, sizeof(jnamebuf));
- *(const void **)&jiov[0].iov_base = "jid";
+IGNORE_WCASTQUAL_BEGIN
+ *(const void**)&jiov[0].iov_base = "jid";
jiov[0].iov_len = sizeof("jid");
- jiov[1].iov_base = &kproc->ki_jid;
+ jiov[1].iov_base = (void*) &kproc->ki_jid;
jiov[1].iov_len = sizeof(kproc->ki_jid);
- *(const void **)&jiov[2].iov_base = "name";
+ *(const void**)&jiov[2].iov_base = "name";
jiov[2].iov_len = sizeof("name");
jiov[3].iov_base = jnamebuf;
jiov[3].iov_len = sizeof(jnamebuf);
- *(const void **)&jiov[4].iov_base = "errmsg";
+ *(const void**)&jiov[4].iov_base = "errmsg";
jiov[4].iov_len = sizeof("errmsg");
jiov[5].iov_base = jail_errmsg;
jiov[5].iov_len = JAIL_ERRMSGLEN;
+IGNORE_WCASTQUAL_END
jail_errmsg[0] = 0;
- jid = jail_get(jiov, 6, 0);
+
+ int jid = jail_get(jiov, 6, 0);
if (jid < 0) {
- if (!jail_errmsg[0])
+ if (!jail_errmsg[0]) {
xSnprintf(jail_errmsg, JAIL_ERRMSGLEN, "jail_get: %s", strerror(errno));
- return NULL;
+ }
} else if (jid == kproc->ki_jid) {
jname = xStrdup(jnamebuf);
- if (jname == NULL)
- strerror_r(errno, jail_errmsg, JAIL_ERRMSGLEN);
- return jname;
- } else {
- return NULL;
}
} else {
- jnamebuf[0]='-';
- jnamebuf[1]='\0';
- jname = xStrdup(jnamebuf);
+ jname = xStrdup("-");
}
+
return jname;
}
-void ProcessList_goThroughEntries(ProcessList* this) {
- FreeBSDProcessList* fpl = (FreeBSDProcessList*) this;
- Settings* settings = this->settings;
+void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
+ FreeBSDProcessList* fpl = (FreeBSDProcessList*) super;
+ const Settings* settings = super->settings;
bool hideKernelThreads = settings->hideKernelThreads;
bool hideUserlandThreads = settings->hideUserlandThreads;
openzfs_sysctl_updateArcStats(&fpl->zfs);
- FreeBSDProcessList_scanMemoryInfo(this);
- FreeBSDProcessList_scanCPUTime(this);
+ FreeBSDProcessList_scanMemoryInfo(super);
+ FreeBSDProcessList_scanCPUTime(super);
+
+ // in pause mode only gather global data for meters (CPU/memory/...)
+ if (pauseProcessUpdate) {
+ return;
+ }
+
+ if (settings->flags & PROCESS_FLAG_FREEBSD_TTY) {
+ FreeBSDProcessList_scanTTYs(super);
+ }
- int cpus = this->cpuCount;
int count = 0;
struct kinfo_proc* kprocs = kvm_getprocs(fpl->kd, KERN_PROC_PROC, 0, &count);
- struct timeval tv;
- gettimeofday(&tv, NULL);
-
for (int i = 0; i < count; i++) {
struct kinfo_proc* kproc = &kprocs[i];
bool preExisting = false;
- bool isIdleProcess = false;
- struct tm date;
- Process* proc = ProcessList_getProcess(this, kproc->ki_pid, &preExisting, (Process_New) FreeBSDProcess_new);
+ // TODO: bool isIdleProcess = false;
+ Process* proc = ProcessList_getProcess(super, kproc->ki_pid, &preExisting, FreeBSDProcess_new);
FreeBSDProcess* fp = (FreeBSDProcess*) proc;
- proc->show = ! ((hideKernelThreads && Process_isKernelThread(fp)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
+ proc->show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
if (!preExisting) {
fp->jid = kproc->ki_jid;
proc->pid = kproc->ki_pid;
- if ( ! ((kproc->ki_pid == 0) || (kproc->ki_pid == 1) ) && kproc->ki_flag & P_SYSTEM)
- fp->kernel = 1;
- else
- fp->kernel = 0;
+ if ( ! ((kproc->ki_pid == 0) || (kproc->ki_pid == 1) ) && kproc->ki_flag & P_SYSTEM) {
+ fp->kernel = 1;
+ } else {
+ fp->kernel = 0;
+ }
proc->ppid = kproc->ki_ppid;
proc->tpgid = kproc->ki_tpgid;
proc->tgid = kproc->ki_pid;
proc->session = kproc->ki_sid;
- proc->tty_nr = kproc->ki_tdev;
proc->pgrp = kproc->ki_pgid;
proc->st_uid = kproc->ki_uid;
proc->starttime_ctime = kproc->ki_start.tv_sec;
- proc->user = UsersTable_getRef(this->usersTable, proc->st_uid);
- ProcessList_add((ProcessList*)this, proc);
+ Process_fillStarttimeBuffer(proc);
+ proc->user = UsersTable_getRef(super->usersTable, proc->st_uid);
+ ProcessList_add(super, proc);
proc->comm = FreeBSDProcessList_readProcessName(fpl->kd, kproc, &proc->basenameOffset);
fp->jname = FreeBSDProcessList_readJailName(kproc);
} else {
- if(fp->jid != kproc->ki_jid) {
+ if (fp->jid != kproc->ki_jid) {
// process can enter jail anytime
fp->jid = kproc->ki_jid;
free(fp->jname);
fp->jname = FreeBSDProcessList_readJailName(kproc);
}
- if (proc->ppid != kproc->ki_ppid) {
- // if there are reapers in the system, process can get reparented anytime
- proc->ppid = kproc->ki_ppid;
- }
- if(proc->st_uid != kproc->ki_uid) {
+ // if there are reapers in the system, process can get reparented anytime
+ proc->ppid = kproc->ki_ppid;
+ if (proc->st_uid != kproc->ki_uid) {
// some processes change users (eg. to lower privs)
proc->st_uid = kproc->ki_uid;
- proc->user = UsersTable_getRef(this->usersTable, proc->st_uid);
+ proc->user = UsersTable_getRef(super->usersTable, proc->st_uid);
}
if (settings->updateProcessNames) {
free(proc->comm);
@@ -442,21 +526,23 @@ void ProcessList_goThroughEntries(ProcessList* this) {
}
// from FreeBSD source /src/usr.bin/top/machine.c
- proc->m_size = kproc->ki_size / 1024 / pageSizeKb;
+ proc->m_virt = kproc->ki_size / pageSize;
proc->m_resident = kproc->ki_rssize;
- proc->percent_mem = (proc->m_resident * PAGE_SIZE_KB) / (double)(this->totalMem) * 100.0;
proc->nlwp = kproc->ki_numthreads;
proc->time = (kproc->ki_runtime + 5000) / 10000;
proc->percent_cpu = 100.0 * ((double)kproc->ki_pctcpu / (double)kernelFScale);
- proc->percent_mem = 100.0 * (proc->m_resident * PAGE_SIZE_KB) / (double)(this->totalMem);
-
- if (proc->percent_cpu > 0.1) {
- // system idle process should own all CPU time left regardless of CPU count
- if ( strcmp("idle", kproc->ki_comm) == 0 ) {
- isIdleProcess = true;
- }
- }
+ proc->percent_mem = 100.0 * (proc->m_resident * pageSizeKb) / (double)(super->totalMem);
+
+ /*
+ * TODO
+ * if (proc->percent_cpu > 0.1) {
+ * // system idle process should own all CPU time left regardless of CPU count
+ * if ( strcmp("idle", kproc->ki_comm) == 0 ) {
+ * isIdleProcess = true;
+ * }
+ * }
+ */
proc->priority = kproc->ki_pri.pri_level - PZERO;
@@ -481,16 +567,16 @@ void ProcessList_goThroughEntries(ProcessList* this) {
default: proc->state = '?';
}
- if (Process_isKernelThread(fp)) {
- this->kernelThreads++;
+ if (settings->flags & PROCESS_FLAG_FREEBSD_TTY) {
+ fp->ttyPath = (kproc->ki_tdev == NODEV) ? nodevStr : Hashtable_get(fpl->ttys, kproc->ki_tdev);
}
- (void) localtime_r((time_t*) &proc->starttime_ctime, &date);
- strftime(proc->starttime_show, 7, ((proc->starttime_ctime > tv.tv_sec - 86400) ? "%R " : "%b%d "), &date);
+ if (Process_isKernelThread(proc))
+ super->kernelThreads++;
- this->totalTasks++;
+ super->totalTasks++;
if (proc->state == 'R')
- this->runningTasks++;
+ super->runningTasks++;
proc->updated = true;
}
}
diff --git a/freebsd/FreeBSDProcessList.h b/freebsd/FreeBSDProcessList.h
index 281bf3e..f18275d 100644
--- a/freebsd/FreeBSDProcessList.h
+++ b/freebsd/FreeBSDProcessList.h
@@ -3,19 +3,21 @@
/*
htop - FreeBSDProcessList.h
(C) 2014 Hisham H. Muhammad
-Released under the GNU GPL, see the COPYING file
+Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
+#include <kvm.h>
+#include <stdbool.h>
+#include <sys/types.h>
+
+#include "Hashtable.h"
+#include "ProcessList.h"
+#include "UsersTable.h"
#include "zfs/ZfsArcStats.h"
-#include <kvm.h>
-#include <sys/param.h>
-#include <sys/jail.h>
-#include <sys/uio.h>
-#include <sys/resource.h>
-#define JAIL_ERRMSGLEN 1024
+#define JAIL_ERRMSGLEN 1024
extern char jail_errmsg[JAIL_ERRMSGLEN];
typedef struct CPUData_ {
@@ -40,11 +42,13 @@ typedef struct FreeBSDProcessList_ {
CPUData* cpus;
- unsigned long *cp_time_o;
- unsigned long *cp_time_n;
+ Hashtable* ttys;
- unsigned long *cp_times_o;
- unsigned long *cp_times_n;
+ unsigned long* cp_time_o;
+ unsigned long* cp_time_n;
+
+ unsigned long* cp_times_o;
+ unsigned long* cp_times_n;
} FreeBSDProcessList;
@@ -52,10 +56,6 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
void ProcessList_delete(ProcessList* this);
-char* FreeBSDProcessList_readProcessName(kvm_t* kd, struct kinfo_proc* kproc, int* basenameEnd);
-
-char* FreeBSDProcessList_readJailName(struct kinfo_proc* kproc);
-
-void ProcessList_goThroughEntries(ProcessList* this);
+void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate);
#endif
diff --git a/freebsd/Platform.c b/freebsd/Platform.c
index c51b37c..bc77cf4 100644
--- a/freebsd/Platform.c
+++ b/freebsd/Platform.c
@@ -1,35 +1,53 @@
/*
htop - freebsd/Platform.c
(C) 2014 Hisham H. Muhammad
-Released under the GNU GPL, see the COPYING file
+Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
#include "Platform.h"
-#include "Meter.h"
+
+#include <devstat.h>
+#include <math.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <time.h>
+#include <net/if.h>
+#include <net/if_mib.h>
+#include <sys/_types.h>
+#include <sys/devicestat.h>
+#include <sys/param.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <vm/vm_param.h>
+
#include "CPUMeter.h"
+#include "ClockMeter.h"
+#include "DateMeter.h"
+#include "DateTimeMeter.h"
+#include "DiskIOMeter.h"
+#include "FreeBSDProcess.h"
+#include "FreeBSDProcessList.h"
+#include "HostnameMeter.h"
+#include "LoadAverageMeter.h"
+#include "Macros.h"
#include "MemoryMeter.h"
+#include "Meter.h"
+#include "NetworkIOMeter.h"
+#include "ProcessList.h"
+#include "Settings.h"
#include "SwapMeter.h"
#include "TasksMeter.h"
-#include "LoadAverageMeter.h"
#include "UptimeMeter.h"
-#include "ClockMeter.h"
-#include "HostnameMeter.h"
+#include "XUtils.h"
#include "zfs/ZfsArcMeter.h"
#include "zfs/ZfsCompressedArcMeter.h"
-#include "FreeBSDProcess.h"
-#include "FreeBSDProcessList.h"
-
-#include <sys/types.h>
-#include <sys/sysctl.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <vm/vm_param.h>
-#include <time.h>
-#include <math.h>
-ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
+ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
int Platform_numberOfFields = LAST_PROCESSFIELD;
@@ -70,15 +88,13 @@ const SignalItem Platform_signals[] = {
{ .name = "33 SIGLIBRT", .number = 33 },
};
-const unsigned int Platform_numberOfSignals = sizeof(Platform_signals)/sizeof(SignalItem);
-
-void Platform_setBindings(Htop_Action* keys) {
- (void) keys;
-}
+const unsigned int Platform_numberOfSignals = ARRAYSIZE(Platform_signals);
-MeterClass* Platform_meterTypes[] = {
+const MeterClass* const Platform_meterTypes[] = {
&CPUMeter_class,
&ClockMeter_class,
+ &DateMeter_class,
+ &DateTimeMeter_class,
&LoadAverageMeter_class,
&LoadMeter_class,
&MemoryMeter_class,
@@ -89,16 +105,37 @@ MeterClass* Platform_meterTypes[] = {
&HostnameMeter_class,
&AllCPUsMeter_class,
&AllCPUs2Meter_class,
+ &AllCPUs4Meter_class,
+ &AllCPUs8Meter_class,
&LeftCPUsMeter_class,
&RightCPUsMeter_class,
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
+ &LeftCPUs4Meter_class,
+ &RightCPUs4Meter_class,
+ &LeftCPUs8Meter_class,
+ &RightCPUs8Meter_class,
&BlankMeter_class,
&ZfsArcMeter_class,
&ZfsCompressedArcMeter_class,
+ &DiskIOMeter_class,
+ &NetworkIOMeter_class,
NULL
};
+void Platform_init(void) {
+ /* no platform-specific setup needed */
+}
+
+void Platform_done(void) {
+ /* no platform-specific cleanup needed */
+}
+
+void Platform_setBindings(Htop_Action* keys) {
+ /* no platform-specific key bindings */
+ (void) keys;
+}
+
int Platform_getUptime() {
struct timeval bootTime, currTime;
int mib[2] = { CTL_KERN, KERN_BOOTTIME };
@@ -141,15 +178,15 @@ int Platform_getMaxPid() {
}
double Platform_setCPUValues(Meter* this, int cpu) {
- FreeBSDProcessList* fpl = (FreeBSDProcessList*) this->pl;
+ const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) this->pl;
int cpus = this->pl->cpuCount;
- CPUData* cpuData;
+ const CPUData* cpuData;
if (cpus == 1) {
- // single CPU box has everything in fpl->cpus[0]
- cpuData = &(fpl->cpus[0]);
+ // single CPU box has everything in fpl->cpus[0]
+ cpuData = &(fpl->cpus[0]);
} else {
- cpuData = &(fpl->cpus[cpu]);
+ cpuData = &(fpl->cpus[cpu]);
}
double percent;
@@ -160,25 +197,25 @@ double Platform_setCPUValues(Meter* this, int cpu) {
if (this->pl->settings->detailedCPUTime) {
v[CPU_METER_KERNEL] = cpuData->systemPercent;
v[CPU_METER_IRQ] = cpuData->irqPercent;
- Meter_setItems(this, 4);
- percent = v[0]+v[1]+v[2]+v[3];
+ this->curItems = 4;
+ percent = v[0] + v[1] + v[2] + v[3];
} else {
v[2] = cpuData->systemAllPercent;
- Meter_setItems(this, 3);
- percent = v[0]+v[1]+v[2];
+ this->curItems = 3;
+ percent = v[0] + v[1] + v[2];
}
percent = CLAMP(percent, 0.0, 100.0);
- if (isnan(percent)) percent = 0.0;
- v[CPU_METER_FREQUENCY] = -1;
+ v[CPU_METER_FREQUENCY] = NAN;
+ v[CPU_METER_TEMPERATURE] = NAN;
return percent;
}
void Platform_setMemoryValues(Meter* this) {
// TODO
- ProcessList* pl = (ProcessList*) this->pl;
+ const ProcessList* pl = this->pl;
this->total = pl->totalMem;
this->values[0] = pl->usedMem;
@@ -187,28 +224,151 @@ void Platform_setMemoryValues(Meter* this) {
}
void Platform_setSwapValues(Meter* this) {
- ProcessList* pl = (ProcessList*) this->pl;
+ const ProcessList* pl = this->pl;
this->total = pl->totalSwap;
this->values[0] = pl->usedSwap;
}
void Platform_setZfsArcValues(Meter* this) {
- FreeBSDProcessList* fpl = (FreeBSDProcessList*) this->pl;
+ const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) this->pl;
ZfsArcMeter_readStats(this, &(fpl->zfs));
}
void Platform_setZfsCompressedArcValues(Meter* this) {
- FreeBSDProcessList* fpl = (FreeBSDProcessList*) this->pl;
+ const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) this->pl;
ZfsCompressedArcMeter_readStats(this, &(fpl->zfs));
}
-void Platform_setTasksValues(Meter* this) {
- // TODO
+char* Platform_getProcessEnv(pid_t pid) {
+ int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ENV, pid };
+
+ size_t capacity = ARG_MAX;
+ char* env = xMalloc(capacity);
+
+ int err = sysctl(mib, 4, env, &capacity, NULL, 0);
+ if (err || capacity == 0) {
+ free(env);
+ return NULL;
+ }
+
+ if (env[capacity - 1] || env[capacity - 2]) {
+ env = xRealloc(env, capacity + 2);
+ env[capacity] = 0;
+ env[capacity + 1] = 0;
+ }
+
+ return env;
}
-char* Platform_getProcessEnv(pid_t pid) {
- // TODO
- return NULL;
+char* Platform_getInodeFilename(pid_t pid, ino_t inode) {
+ (void)pid;
+ (void)inode;
+ return NULL;
+}
+
+FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) {
+ (void)pid;
+ return NULL;
+}
+
+bool Platform_getDiskIO(DiskIOData* data) {
+
+ if (devstat_checkversion(NULL) < 0)
+ return false;
+
+ struct devinfo info = { 0 };
+ struct statinfo current = { .dinfo = &info };
+
+ // get number of devices
+ if (devstat_getdevs(NULL, &current) < 0)
+ return false;
+
+ int count = current.dinfo->numdevs;
+
+ unsigned long int bytesReadSum = 0, bytesWriteSum = 0, timeSpendSum = 0;
+
+ // get data
+ for (int i = 0; i < count; i++) {
+ uint64_t bytes_read, bytes_write;
+ long double busy_time;
+
+ devstat_compute_statistics(&current.dinfo->devices[i],
+ NULL,
+ 1.0,
+ DSM_TOTAL_BYTES_READ, &bytes_read,
+ DSM_TOTAL_BYTES_WRITE, &bytes_write,
+ DSM_TOTAL_BUSY_TIME, &busy_time,
+ DSM_NONE);
+
+ bytesReadSum += bytes_read;
+ bytesWriteSum += bytes_write;
+ timeSpendSum += 1000 * busy_time;
+ }
+
+ data->totalBytesRead = bytesReadSum;
+ data->totalBytesWritten = bytesWriteSum;
+ data->totalMsTimeSpend = timeSpendSum;
+ return true;
+}
+
+bool Platform_getNetworkIO(unsigned long int* bytesReceived,
+ unsigned long int* packetsReceived,
+ unsigned long int* bytesTransmitted,
+ unsigned long int* packetsTransmitted) {
+ int r;
+
+ // get number of interfaces
+ int count;
+ size_t countLen = sizeof(count);
+ const int countMib[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT };
+
+ r = sysctl(countMib, ARRAYSIZE(countMib), &count, &countLen, NULL, 0);
+ if (r < 0)
+ return false;
+
+
+ unsigned long int bytesReceivedSum = 0, packetsReceivedSum = 0, bytesTransmittedSum = 0, packetsTransmittedSum = 0;
+
+ for (int i = 1; i <= count; i++) {
+ struct ifmibdata ifmd;
+ size_t ifmdLen = sizeof(ifmd);
+
+ const int dataMib[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, i, IFDATA_GENERAL };
+
+ r = sysctl(dataMib, ARRAYSIZE(dataMib), &ifmd, &ifmdLen, NULL, 0);
+ if (r < 0)
+ continue;
+
+ if (ifmd.ifmd_flags & IFF_LOOPBACK)
+ continue;
+
+ bytesReceivedSum += ifmd.ifmd_data.ifi_ibytes;
+ packetsReceivedSum += ifmd.ifmd_data.ifi_ipackets;
+ bytesTransmittedSum += ifmd.ifmd_data.ifi_obytes;
+ packetsTransmittedSum += ifmd.ifmd_data.ifi_opackets;
+ }
+
+ *bytesReceived = bytesReceivedSum;
+ *packetsReceived = packetsReceivedSum;
+ *bytesTransmitted = bytesTransmittedSum;
+ *packetsTransmitted = packetsTransmittedSum;
+ return true;
+}
+
+void Platform_getBattery(double* percent, ACPresence* isOnAC) {
+ int life;
+ size_t life_len = sizeof(life);
+ if (sysctlbyname("hw.acpi.battery.life", &life, &life_len, NULL, 0) == -1)
+ *percent = NAN;
+ else
+ *percent = life;
+
+ int acline;
+ size_t acline_len = sizeof(acline);
+ if (sysctlbyname("hw.acpi.acline", &acline, &acline_len, NULL, 0) == -1)
+ *isOnAC = AC_ERROR;
+ else
+ *isOnAC = acline == 0 ? AC_ABSENT : AC_PRESENT;
}
diff --git a/freebsd/Platform.h b/freebsd/Platform.h
index 1a18055..5b3b019 100644
--- a/freebsd/Platform.h
+++ b/freebsd/Platform.h
@@ -3,14 +3,22 @@
/*
htop - freebsd/Platform.h
(C) 2014 Hisham H. Muhammad
-Released under the GNU GPL, see the COPYING file
+Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
+#include <stdbool.h>
+#include <sys/types.h>
+
#include "Action.h"
#include "BatteryMeter.h"
+#include "DiskIOMeter.h"
+#include "Meter.h"
+#include "Process.h"
+#include "ProcessLocksScreen.h"
#include "SignalsPanel.h"
+
extern ProcessFieldData Process_fields[];
extern ProcessField Platform_defaultFields[];
@@ -21,15 +29,19 @@ extern const SignalItem Platform_signals[];
extern const unsigned int Platform_numberOfSignals;
-void Platform_setBindings(Htop_Action* keys);
+extern const MeterClass* const Platform_meterTypes[];
-extern MeterClass* Platform_meterTypes[];
+void Platform_init(void);
+
+void Platform_done(void);
+
+void Platform_setBindings(Htop_Action* keys);
-int Platform_getUptime();
+int Platform_getUptime(void);
void Platform_getLoadAverage(double* one, double* five, double* fifteen);
-int Platform_getMaxPid();
+int Platform_getMaxPid(void);
double Platform_setCPUValues(Meter* this, int cpu);
@@ -41,8 +53,19 @@ void Platform_setZfsArcValues(Meter* this);
void Platform_setZfsCompressedArcValues(Meter* this);
-void Platform_setTasksValues(Meter* this);
-
char* Platform_getProcessEnv(pid_t pid);
+char* Platform_getInodeFilename(pid_t pid, ino_t inode);
+
+FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid);
+
+bool Platform_getDiskIO(DiskIOData* data);
+
+bool Platform_getNetworkIO(unsigned long int* bytesReceived,
+ unsigned long int* packetsReceived,
+ unsigned long int* bytesTransmitted,
+ unsigned long int* packetsTransmitted);
+
+void Platform_getBattery(double* percent, ACPresence* isOnAC);
+
#endif

© 2014-2024 Faster IT GmbH | imprint | privacy policy