2014-11-27 18:27:34 +00:00
|
|
|
/*
|
2014-11-27 21:33:37 +00:00
|
|
|
htop - freebsd/Platform.c
|
2014-11-27 18:27:34 +00:00
|
|
|
(C) 2014 Hisham H. Muhammad
|
2020-10-05 07:51:32 +00:00
|
|
|
Released under the GNU GPLv2, see the COPYING file
|
2014-11-27 18:27:34 +00:00
|
|
|
in the source distribution for its full text.
|
|
|
|
*/
|
|
|
|
|
kfreeBSD: include config.h for _GNU_SOURCE
strcasestr(3) is a GNU extension and when compiling freebsd/Platform.c
on kfreebsd for Debian <string.h> is included before we define
_GNU_SOURCE, so the function is not available.
In file included from ./Object.h:16,
from ./ListItem.h:12,
from ./Meter.h:16,
from ./Header.h:10,
from ./Action.h:15,
from freebsd/Platform.h:13,
from freebsd/Platform.c:8:
./XUtils.h: In function ‘String_contains_i’:
./XUtils.h:43:11: warning: implicit declaration of function ‘strcasestr’; did you mean ‘strcasecmp’? [-Wimplicit-function-declaration]
43 | return strcasestr(s1, s2) != NULL;
| ^~~~~~~~~~
| strcasecmp
./XUtils.h:43:30: warning: comparison between pointer and integer
43 | return strcasestr(s1, s2) != NULL;
| ^~
In file included from ./Object.h:16,
from ./ProcessList.h:16,
from freebsd/FreeBSDProcessList.h:15,
from freebsd/FreeBSDProcessList.c:8:
./XUtils.h: In function ‘String_contains_i’:
./XUtils.h:43:11: warning: implicit declaration of function ‘strcasestr’; did you mean ‘strcasecmp’? [-Wimplicit-function-declaration]
43 | return strcasestr(s1, s2) != NULL;
| ^~~~~~~~~~
| strcasecmp
./XUtils.h:43:30: warning: comparison between pointer and integer
43 | return strcasestr(s1, s2) != NULL;
| ^~
2021-01-12 16:02:16 +00:00
|
|
|
#include "config.h" // IWYU pragma: keep
|
|
|
|
|
2014-11-27 18:27:34 +00:00
|
|
|
#include "Platform.h"
|
2020-10-21 14:19:22 +00:00
|
|
|
|
2020-10-21 15:06:32 +00:00
|
|
|
#include <devstat.h>
|
2020-10-21 14:19:22 +00:00
|
|
|
#include <math.h>
|
2020-11-18 14:12:18 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
2020-10-21 14:19:22 +00:00
|
|
|
#include <time.h>
|
|
|
|
#include <net/if.h>
|
|
|
|
#include <net/if_mib.h>
|
2020-11-18 14:12:18 +00:00
|
|
|
#include <sys/_types.h>
|
|
|
|
#include <sys/devicestat.h>
|
|
|
|
#include <sys/param.h>
|
2020-10-21 14:19:22 +00:00
|
|
|
#include <sys/resource.h>
|
2020-11-18 14:12:18 +00:00
|
|
|
#include <sys/socket.h>
|
2020-10-21 14:19:22 +00:00
|
|
|
#include <sys/sysctl.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <vm/vm_param.h>
|
|
|
|
|
2014-11-27 21:33:37 +00:00
|
|
|
#include "CPUMeter.h"
|
|
|
|
#include "ClockMeter.h"
|
2020-10-05 11:52:58 +00:00
|
|
|
#include "DateMeter.h"
|
|
|
|
#include "DateTimeMeter.h"
|
2020-10-21 15:06:32 +00:00
|
|
|
#include "DiskIOMeter.h"
|
2020-10-21 14:19:22 +00:00
|
|
|
#include "FreeBSDProcess.h"
|
|
|
|
#include "FreeBSDProcessList.h"
|
2014-11-27 21:33:37 +00:00
|
|
|
#include "HostnameMeter.h"
|
2020-10-21 14:19:22 +00:00
|
|
|
#include "LoadAverageMeter.h"
|
|
|
|
#include "Macros.h"
|
|
|
|
#include "MemoryMeter.h"
|
|
|
|
#include "Meter.h"
|
2020-10-08 14:34:54 +00:00
|
|
|
#include "NetworkIOMeter.h"
|
2020-11-18 14:12:18 +00:00
|
|
|
#include "ProcessList.h"
|
|
|
|
#include "Settings.h"
|
2020-10-21 14:19:22 +00:00
|
|
|
#include "SwapMeter.h"
|
2021-01-27 09:45:48 +00:00
|
|
|
#include "SysArchMeter.h"
|
2020-10-21 14:19:22 +00:00
|
|
|
#include "TasksMeter.h"
|
|
|
|
#include "UptimeMeter.h"
|
2020-11-18 14:12:18 +00:00
|
|
|
#include "XUtils.h"
|
2019-07-06 04:27:49 +00:00
|
|
|
#include "zfs/ZfsArcMeter.h"
|
2019-09-03 18:26:02 +00:00
|
|
|
#include "zfs/ZfsCompressedArcMeter.h"
|
2014-11-27 21:44:20 +00:00
|
|
|
|
2014-11-27 18:27:34 +00:00
|
|
|
|
2020-12-19 17:10:03 +00:00
|
|
|
const ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
2015-03-16 06:13:42 +00:00
|
|
|
|
2016-08-30 12:41:17 +00:00
|
|
|
const SignalItem Platform_signals[] = {
|
2015-10-06 06:02:49 +00:00
|
|
|
{ .name = " 0 Cancel", .number = 0 },
|
|
|
|
{ .name = " 1 SIGHUP", .number = 1 },
|
|
|
|
{ .name = " 2 SIGINT", .number = 2 },
|
|
|
|
{ .name = " 3 SIGQUIT", .number = 3 },
|
|
|
|
{ .name = " 4 SIGILL", .number = 4 },
|
|
|
|
{ .name = " 5 SIGTRAP", .number = 5 },
|
|
|
|
{ .name = " 6 SIGABRT", .number = 6 },
|
|
|
|
{ .name = " 7 SIGEMT", .number = 7 },
|
|
|
|
{ .name = " 8 SIGFPE", .number = 8 },
|
|
|
|
{ .name = " 9 SIGKILL", .number = 9 },
|
|
|
|
{ .name = "10 SIGBUS", .number = 10 },
|
|
|
|
{ .name = "11 SIGSEGV", .number = 11 },
|
|
|
|
{ .name = "12 SIGSYS", .number = 12 },
|
|
|
|
{ .name = "13 SIGPIPE", .number = 13 },
|
|
|
|
{ .name = "14 SIGALRM", .number = 14 },
|
|
|
|
{ .name = "15 SIGTERM", .number = 15 },
|
|
|
|
{ .name = "16 SIGURG", .number = 16 },
|
|
|
|
{ .name = "17 SIGSTOP", .number = 17 },
|
|
|
|
{ .name = "18 SIGTSTP", .number = 18 },
|
|
|
|
{ .name = "19 SIGCONT", .number = 19 },
|
|
|
|
{ .name = "20 SIGCHLD", .number = 20 },
|
|
|
|
{ .name = "21 SIGTTIN", .number = 21 },
|
|
|
|
{ .name = "22 SIGTTOU", .number = 22 },
|
|
|
|
{ .name = "23 SIGIO", .number = 23 },
|
|
|
|
{ .name = "24 SIGXCPU", .number = 24 },
|
|
|
|
{ .name = "25 SIGXFSZ", .number = 25 },
|
|
|
|
{ .name = "26 SIGVTALRM", .number = 26 },
|
|
|
|
{ .name = "27 SIGPROF", .number = 27 },
|
|
|
|
{ .name = "28 SIGWINCH", .number = 28 },
|
|
|
|
{ .name = "29 SIGINFO", .number = 29 },
|
|
|
|
{ .name = "30 SIGUSR1", .number = 30 },
|
|
|
|
{ .name = "31 SIGUSR2", .number = 31 },
|
|
|
|
{ .name = "32 SIGTHR", .number = 32 },
|
|
|
|
{ .name = "33 SIGLIBRT", .number = 33 },
|
|
|
|
};
|
|
|
|
|
2020-10-03 20:00:27 +00:00
|
|
|
const unsigned int Platform_numberOfSignals = ARRAYSIZE(Platform_signals);
|
2015-10-06 06:02:49 +00:00
|
|
|
|
2020-10-05 11:19:50 +00:00
|
|
|
const MeterClass* const Platform_meterTypes[] = {
|
2014-11-27 21:33:37 +00:00
|
|
|
&CPUMeter_class,
|
|
|
|
&ClockMeter_class,
|
2020-10-05 11:52:58 +00:00
|
|
|
&DateMeter_class,
|
|
|
|
&DateTimeMeter_class,
|
2014-11-27 21:33:37 +00:00
|
|
|
&LoadAverageMeter_class,
|
|
|
|
&LoadMeter_class,
|
|
|
|
&MemoryMeter_class,
|
|
|
|
&SwapMeter_class,
|
|
|
|
&TasksMeter_class,
|
|
|
|
&UptimeMeter_class,
|
|
|
|
&BatteryMeter_class,
|
|
|
|
&HostnameMeter_class,
|
2021-01-27 09:45:48 +00:00
|
|
|
&SysArchMeter_class,
|
2014-11-27 21:33:37 +00:00
|
|
|
&AllCPUsMeter_class,
|
|
|
|
&AllCPUs2Meter_class,
|
2020-09-24 19:50:29 +00:00
|
|
|
&AllCPUs4Meter_class,
|
2020-09-24 19:56:40 +00:00
|
|
|
&AllCPUs8Meter_class,
|
2014-11-27 21:33:37 +00:00
|
|
|
&LeftCPUsMeter_class,
|
|
|
|
&RightCPUsMeter_class,
|
|
|
|
&LeftCPUs2Meter_class,
|
|
|
|
&RightCPUs2Meter_class,
|
2020-09-24 19:50:29 +00:00
|
|
|
&LeftCPUs4Meter_class,
|
|
|
|
&RightCPUs4Meter_class,
|
2020-09-24 19:56:40 +00:00
|
|
|
&LeftCPUs8Meter_class,
|
|
|
|
&RightCPUs8Meter_class,
|
2014-11-27 21:33:37 +00:00
|
|
|
&BlankMeter_class,
|
2019-07-06 04:27:49 +00:00
|
|
|
&ZfsArcMeter_class,
|
2019-09-03 18:26:02 +00:00
|
|
|
&ZfsCompressedArcMeter_class,
|
2020-10-21 15:06:32 +00:00
|
|
|
&DiskIOMeter_class,
|
2020-10-08 14:34:54 +00:00
|
|
|
&NetworkIOMeter_class,
|
2014-11-27 21:33:37 +00:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2020-11-19 01:32:07 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-11-27 21:44:20 +00:00
|
|
|
int Platform_getUptime() {
|
|
|
|
struct timeval bootTime, currTime;
|
2021-01-27 14:11:50 +00:00
|
|
|
const int mib[2] = { CTL_KERN, KERN_BOOTTIME };
|
2014-11-27 21:44:20 +00:00
|
|
|
size_t size = sizeof(bootTime);
|
2015-12-12 23:21:02 +00:00
|
|
|
|
2014-11-27 21:44:20 +00:00
|
|
|
int err = sysctl(mib, 2, &bootTime, &size, NULL, 0);
|
|
|
|
if (err) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
gettimeofday(&currTime, NULL);
|
|
|
|
|
|
|
|
return (int) difftime(currTime.tv_sec, bootTime.tv_sec);
|
|
|
|
}
|
2014-11-27 22:03:29 +00:00
|
|
|
|
|
|
|
void Platform_getLoadAverage(double* one, double* five, double* fifteen) {
|
|
|
|
struct loadavg loadAverage;
|
2021-01-27 14:11:50 +00:00
|
|
|
const int mib[2] = { CTL_VM, VM_LOADAVG };
|
2014-11-27 22:03:29 +00:00
|
|
|
size_t size = sizeof(loadAverage);
|
2015-12-12 23:21:02 +00:00
|
|
|
|
2014-11-27 22:03:29 +00:00
|
|
|
int err = sysctl(mib, 2, &loadAverage, &size, NULL, 0);
|
|
|
|
if (err) {
|
|
|
|
*one = 0;
|
|
|
|
*five = 0;
|
|
|
|
*fifteen = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
*one = (double) loadAverage.ldavg[0] / loadAverage.fscale;
|
|
|
|
*five = (double) loadAverage.ldavg[1] / loadAverage.fscale;
|
|
|
|
*fifteen = (double) loadAverage.ldavg[2] / loadAverage.fscale;
|
|
|
|
}
|
2014-11-27 22:18:01 +00:00
|
|
|
|
|
|
|
int Platform_getMaxPid() {
|
|
|
|
int maxPid;
|
|
|
|
size_t size = sizeof(maxPid);
|
|
|
|
int err = sysctlbyname("kern.pid_max", &maxPid, &size, NULL, 0);
|
|
|
|
if (err) {
|
|
|
|
return 99999;
|
|
|
|
}
|
|
|
|
return maxPid;
|
|
|
|
}
|
2014-11-27 23:07:42 +00:00
|
|
|
|
2015-03-16 06:13:42 +00:00
|
|
|
double Platform_setCPUValues(Meter* this, int cpu) {
|
2020-10-21 19:25:50 +00:00
|
|
|
const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) this->pl;
|
2015-12-12 23:21:02 +00:00
|
|
|
int cpus = this->pl->cpuCount;
|
2020-10-21 19:25:50 +00:00
|
|
|
const CPUData* cpuData;
|
2015-12-12 23:21:02 +00:00
|
|
|
|
|
|
|
if (cpus == 1) {
|
2020-10-31 21:14:27 +00:00
|
|
|
// single CPU box has everything in fpl->cpus[0]
|
|
|
|
cpuData = &(fpl->cpus[0]);
|
2015-12-12 23:21:02 +00:00
|
|
|
} else {
|
2020-10-31 21:14:27 +00:00
|
|
|
cpuData = &(fpl->cpus[cpu]);
|
2015-12-12 23:21:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
double percent;
|
|
|
|
double* v = this->values;
|
|
|
|
|
2016-04-28 19:42:18 +00:00
|
|
|
v[CPU_METER_NICE] = cpuData->nicePercent;
|
|
|
|
v[CPU_METER_NORMAL] = cpuData->userPercent;
|
2015-12-12 23:21:02 +00:00
|
|
|
if (this->pl->settings->detailedCPUTime) {
|
2016-04-28 19:42:18 +00:00
|
|
|
v[CPU_METER_KERNEL] = cpuData->systemPercent;
|
|
|
|
v[CPU_METER_IRQ] = cpuData->irqPercent;
|
2020-10-04 15:55:08 +00:00
|
|
|
this->curItems = 4;
|
2020-10-31 22:28:02 +00:00
|
|
|
percent = v[0] + v[1] + v[2] + v[3];
|
2015-12-12 23:21:02 +00:00
|
|
|
} else {
|
2016-04-28 19:42:18 +00:00
|
|
|
v[2] = cpuData->systemAllPercent;
|
2020-10-04 15:55:08 +00:00
|
|
|
this->curItems = 3;
|
2020-10-31 22:28:02 +00:00
|
|
|
percent = v[0] + v[1] + v[2];
|
2015-12-12 23:21:02 +00:00
|
|
|
}
|
|
|
|
|
Introduce CLAMP macro. Unify all MIN(MAX(a,b),c) uses.
With the CLAMP macro replacing the combination of MIN and MAX, we will
have at least two advantages:
1. It's more obvious semantically.
2. There are no more mixes of confusing uses like MIN(MAX(a,b),c) and
MAX(MIN(a,b),c) and MIN(a,MAX(b,c)) appearing everywhere. We unify
the 'clamping' with a single macro.
Note that the behavior of this CLAMP macro is different from
the combination `MAX(low,MIN(x,high))`.
* This CLAMP macro expands to two comparisons instead of three from
MAX and MIN combination. In theory, this makes the code slightly
smaller, in case that (low) or (high) or both are computed at
runtime, so that compilers cannot optimize them. (The third
comparison will matter if (low)>(high); see below.)
* CLAMP has a side effect, that if (low)>(high) it will produce weird
results. Unlike MIN & MAX which will force either (low) or (high) to
win. No assertion of ((low)<=(high)) is done in this macro, for now.
This CLAMP macro is implemented like described in glib
<http://developer.gnome.org/glib/stable/glib-Standard-Macros.html>
and does not handle weird uses like CLAMP(a++, low++, high--) .
2016-01-15 12:26:01 +00:00
|
|
|
percent = CLAMP(percent, 0.0, 100.0);
|
2019-08-11 00:17:45 +00:00
|
|
|
|
2020-09-07 10:24:32 +00:00
|
|
|
v[CPU_METER_FREQUENCY] = NAN;
|
2020-09-10 17:56:33 +00:00
|
|
|
v[CPU_METER_TEMPERATURE] = NAN;
|
2019-08-11 00:17:45 +00:00
|
|
|
|
2015-12-12 23:21:02 +00:00
|
|
|
return percent;
|
2015-03-16 06:13:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Platform_setMemoryValues(Meter* this) {
|
2020-10-21 19:25:50 +00:00
|
|
|
const ProcessList* pl = this->pl;
|
2015-12-13 03:11:35 +00:00
|
|
|
|
|
|
|
this->total = pl->totalMem;
|
|
|
|
this->values[0] = pl->usedMem;
|
|
|
|
this->values[1] = pl->buffersMem;
|
2021-03-17 15:32:16 +00:00
|
|
|
// this->values[2] = "shared memory, like tmpfs and shm"
|
|
|
|
this->values[3] = pl->cachedMem;
|
|
|
|
// this->values[4] = "available memory"
|
2015-03-16 06:13:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Platform_setSwapValues(Meter* this) {
|
2020-10-21 19:25:50 +00:00
|
|
|
const ProcessList* pl = this->pl;
|
2015-12-13 03:16:06 +00:00
|
|
|
this->total = pl->totalSwap;
|
|
|
|
this->values[0] = pl->usedSwap;
|
2021-01-07 13:38:18 +00:00
|
|
|
this->values[1] = NAN;
|
2014-11-27 23:07:42 +00:00
|
|
|
}
|
|
|
|
|
2019-07-06 04:27:49 +00:00
|
|
|
void Platform_setZfsArcValues(Meter* this) {
|
2020-10-21 19:25:50 +00:00
|
|
|
const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) this->pl;
|
2019-07-06 04:27:49 +00:00
|
|
|
|
2019-09-03 18:21:33 +00:00
|
|
|
ZfsArcMeter_readStats(this, &(fpl->zfs));
|
2019-07-06 04:27:49 +00:00
|
|
|
}
|
|
|
|
|
2019-09-03 18:26:02 +00:00
|
|
|
void Platform_setZfsCompressedArcValues(Meter* this) {
|
2020-10-21 19:25:50 +00:00
|
|
|
const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) this->pl;
|
2019-09-03 18:26:02 +00:00
|
|
|
|
|
|
|
ZfsCompressedArcMeter_readStats(this, &(fpl->zfs));
|
|
|
|
}
|
|
|
|
|
2015-12-03 21:16:10 +00:00
|
|
|
char* Platform_getProcessEnv(pid_t pid) {
|
2021-01-27 14:11:50 +00:00
|
|
|
const int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ENV, pid };
|
2020-10-23 20:31:20 +00:00
|
|
|
|
|
|
|
size_t capacity = ARG_MAX;
|
2020-10-26 15:40:18 +00:00
|
|
|
char* env = xMalloc(capacity);
|
2020-10-23 20:31:20 +00:00
|
|
|
|
|
|
|
int err = sysctl(mib, 4, env, &capacity, NULL, 0);
|
2020-12-05 19:34:23 +00:00
|
|
|
if (err || capacity == 0) {
|
2020-10-23 20:31:20 +00:00
|
|
|
free(env);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-10-31 22:28:02 +00:00
|
|
|
if (env[capacity - 1] || env[capacity - 2]) {
|
|
|
|
env = xRealloc(env, capacity + 2);
|
2020-10-23 20:31:20 +00:00
|
|
|
env[capacity] = 0;
|
2020-10-31 22:28:02 +00:00
|
|
|
env[capacity + 1] = 0;
|
2020-10-23 20:31:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return env;
|
2015-12-03 21:16:10 +00:00
|
|
|
}
|
2020-09-13 17:46:34 +00:00
|
|
|
|
2020-11-11 21:15:35 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-10-21 15:06:32 +00:00
|
|
|
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, ¤t) < 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int count = current.dinfo->numdevs;
|
|
|
|
|
2021-03-01 01:10:18 +00:00
|
|
|
unsigned long long int bytesReadSum = 0, bytesWriteSum = 0, timeSpendSum = 0;
|
2020-10-21 15:06:32 +00:00
|
|
|
|
|
|
|
// get data
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
uint64_t bytes_read, bytes_write;
|
|
|
|
long double busy_time;
|
|
|
|
|
|
|
|
devstat_compute_statistics(¤t.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;
|
2020-09-13 17:46:34 +00:00
|
|
|
}
|
2020-10-08 14:34:54 +00:00
|
|
|
|
2021-03-01 00:55:15 +00:00
|
|
|
bool Platform_getNetworkIO(NetworkIOData* data) {
|
2020-10-08 14:34:54 +00:00
|
|
|
// get number of interfaces
|
|
|
|
int count;
|
|
|
|
size_t countLen = sizeof(count);
|
|
|
|
const int countMib[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT };
|
|
|
|
|
2021-03-02 01:14:44 +00:00
|
|
|
int r = sysctl(countMib, ARRAYSIZE(countMib), &count, &countLen, NULL, 0);
|
2020-10-20 19:40:51 +00:00
|
|
|
if (r < 0)
|
|
|
|
return false;
|
|
|
|
|
2021-03-01 00:55:15 +00:00
|
|
|
memset(data, 0, sizeof(NetworkIOData));
|
2020-10-08 14:34:54 +00:00
|
|
|
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;
|
|
|
|
|
2021-03-01 00:55:15 +00:00
|
|
|
data->bytesReceived += ifmd.ifmd_data.ifi_ibytes;
|
|
|
|
data->packetsReceived += ifmd.ifmd_data.ifi_ipackets;
|
|
|
|
data->bytesTransmitted += ifmd.ifmd_data.ifi_obytes;
|
|
|
|
data->packetsTransmitted += ifmd.ifmd_data.ifi_opackets;
|
2020-10-08 14:34:54 +00:00
|
|
|
}
|
|
|
|
|
2020-10-20 19:40:51 +00:00
|
|
|
return true;
|
2020-10-08 14:34:54 +00:00
|
|
|
}
|
2020-11-17 07:12:38 +00:00
|
|
|
|
2020-11-25 11:46:00 +00:00
|
|
|
void Platform_getBattery(double* percent, ACPresence* isOnAC) {
|
2020-11-17 07:12:38 +00:00
|
|
|
int life;
|
|
|
|
size_t life_len = sizeof(life);
|
|
|
|
if (sysctlbyname("hw.acpi.battery.life", &life, &life_len, NULL, 0) == -1)
|
2020-11-25 11:46:00 +00:00
|
|
|
*percent = NAN;
|
2020-11-17 07:12:38 +00:00
|
|
|
else
|
2020-11-25 11:46:00 +00:00
|
|
|
*percent = life;
|
2020-11-17 07:12:38 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|