mirror of https://github.com/xzeldon/htop.git
Add SystemdMeter
This commit is contained in:
parent
ab17ef4dc0
commit
2a9e8ca074
18
CRT.c
18
CRT.c
|
@ -95,9 +95,10 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||||
[METER_TEXT] = ColorPair(Cyan,Black),
|
[METER_TEXT] = ColorPair(Cyan,Black),
|
||||||
[METER_VALUE] = A_BOLD | ColorPair(Cyan,Black),
|
[METER_VALUE] = A_BOLD | ColorPair(Cyan,Black),
|
||||||
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red,Black),
|
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red,Black),
|
||||||
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(White,Black),
|
|
||||||
[METER_VALUE_IOREAD] = ColorPair(Green,Black),
|
[METER_VALUE_IOREAD] = ColorPair(Green,Black),
|
||||||
[METER_VALUE_IOWRITE] = ColorPair(Blue,Black),
|
[METER_VALUE_IOWRITE] = ColorPair(Blue,Black),
|
||||||
|
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(White,Black),
|
||||||
|
[METER_VALUE_OK] = ColorPair(Green,Black),
|
||||||
[LED_COLOR] = ColorPair(Green,Black),
|
[LED_COLOR] = ColorPair(Green,Black),
|
||||||
[TASKS_RUNNING] = A_BOLD | ColorPair(Green,Black),
|
[TASKS_RUNNING] = A_BOLD | ColorPair(Green,Black),
|
||||||
[PROCESS] = A_NORMAL,
|
[PROCESS] = A_NORMAL,
|
||||||
|
@ -173,9 +174,10 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||||
[METER_TEXT] = A_NORMAL,
|
[METER_TEXT] = A_NORMAL,
|
||||||
[METER_VALUE] = A_BOLD,
|
[METER_VALUE] = A_BOLD,
|
||||||
[METER_VALUE_ERROR] = A_BOLD,
|
[METER_VALUE_ERROR] = A_BOLD,
|
||||||
[METER_VALUE_NOTICE] = A_BOLD,
|
|
||||||
[METER_VALUE_IOREAD] = A_NORMAL,
|
[METER_VALUE_IOREAD] = A_NORMAL,
|
||||||
[METER_VALUE_IOWRITE] = A_NORMAL,
|
[METER_VALUE_IOWRITE] = A_NORMAL,
|
||||||
|
[METER_VALUE_NOTICE] = A_BOLD,
|
||||||
|
[METER_VALUE_OK] = A_NORMAL,
|
||||||
[LED_COLOR] = A_NORMAL,
|
[LED_COLOR] = A_NORMAL,
|
||||||
[TASKS_RUNNING] = A_BOLD,
|
[TASKS_RUNNING] = A_BOLD,
|
||||||
[PROCESS] = A_NORMAL,
|
[PROCESS] = A_NORMAL,
|
||||||
|
@ -251,9 +253,10 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||||
[METER_TEXT] = ColorPair(Blue,White),
|
[METER_TEXT] = ColorPair(Blue,White),
|
||||||
[METER_VALUE] = ColorPair(Black,White),
|
[METER_VALUE] = ColorPair(Black,White),
|
||||||
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red,White),
|
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red,White),
|
||||||
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(Yellow,White),
|
|
||||||
[METER_VALUE_IOREAD] = ColorPair(Green,White),
|
[METER_VALUE_IOREAD] = ColorPair(Green,White),
|
||||||
[METER_VALUE_IOWRITE] = ColorPair(Yellow,White),
|
[METER_VALUE_IOWRITE] = ColorPair(Yellow,White),
|
||||||
|
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(Yellow,White),
|
||||||
|
[METER_VALUE_OK] = ColorPair(Green,White),
|
||||||
[LED_COLOR] = ColorPair(Green,White),
|
[LED_COLOR] = ColorPair(Green,White),
|
||||||
[TASKS_RUNNING] = ColorPair(Green,White),
|
[TASKS_RUNNING] = ColorPair(Green,White),
|
||||||
[PROCESS] = ColorPair(Black,White),
|
[PROCESS] = ColorPair(Black,White),
|
||||||
|
@ -329,9 +332,10 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||||
[METER_TEXT] = ColorPair(Blue,Black),
|
[METER_TEXT] = ColorPair(Blue,Black),
|
||||||
[METER_VALUE] = ColorPair(Blue,Black),
|
[METER_VALUE] = ColorPair(Blue,Black),
|
||||||
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red,Black),
|
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red,Black),
|
||||||
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(Yellow,Black),
|
|
||||||
[METER_VALUE_IOREAD] = ColorPair(Green,Black),
|
[METER_VALUE_IOREAD] = ColorPair(Green,Black),
|
||||||
[METER_VALUE_IOWRITE] = ColorPair(Yellow,Black),
|
[METER_VALUE_IOWRITE] = ColorPair(Yellow,Black),
|
||||||
|
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(Yellow,Black),
|
||||||
|
[METER_VALUE_OK] = ColorPair(Green,Black),
|
||||||
[LED_COLOR] = ColorPair(Green,Black),
|
[LED_COLOR] = ColorPair(Green,Black),
|
||||||
[TASKS_RUNNING] = ColorPair(Green,Black),
|
[TASKS_RUNNING] = ColorPair(Green,Black),
|
||||||
[PROCESS] = ColorPair(Blue,Black),
|
[PROCESS] = ColorPair(Blue,Black),
|
||||||
|
@ -407,9 +411,10 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||||
[METER_TEXT] = ColorPair(Cyan,Blue),
|
[METER_TEXT] = ColorPair(Cyan,Blue),
|
||||||
[METER_VALUE] = A_BOLD | ColorPair(Cyan,Blue),
|
[METER_VALUE] = A_BOLD | ColorPair(Cyan,Blue),
|
||||||
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red,Blue),
|
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red,Blue),
|
||||||
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(White,Blue),
|
|
||||||
[METER_VALUE_IOREAD] = ColorPair(Green,Blue),
|
[METER_VALUE_IOREAD] = ColorPair(Green,Blue),
|
||||||
[METER_VALUE_IOWRITE] = ColorPair(Black,Blue),
|
[METER_VALUE_IOWRITE] = ColorPair(Black,Blue),
|
||||||
|
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(White,Blue),
|
||||||
|
[METER_VALUE_OK] = ColorPair(Green,Blue),
|
||||||
[LED_COLOR] = ColorPair(Green,Blue),
|
[LED_COLOR] = ColorPair(Green,Blue),
|
||||||
[TASKS_RUNNING] = A_BOLD | ColorPair(Green,Blue),
|
[TASKS_RUNNING] = A_BOLD | ColorPair(Green,Blue),
|
||||||
[PROCESS] = ColorPair(White,Blue),
|
[PROCESS] = ColorPair(White,Blue),
|
||||||
|
@ -485,9 +490,10 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
||||||
[METER_TEXT] = ColorPair(Cyan,Black),
|
[METER_TEXT] = ColorPair(Cyan,Black),
|
||||||
[METER_VALUE] = ColorPair(Green,Black),
|
[METER_VALUE] = ColorPair(Green,Black),
|
||||||
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red,Black),
|
[METER_VALUE_ERROR] = A_BOLD | ColorPair(Red,Black),
|
||||||
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(Yellow,Black),
|
|
||||||
[METER_VALUE_IOREAD] = ColorPair(Green,Black),
|
[METER_VALUE_IOREAD] = ColorPair(Green,Black),
|
||||||
[METER_VALUE_IOWRITE] = ColorPair(Blue,Black),
|
[METER_VALUE_IOWRITE] = ColorPair(Blue,Black),
|
||||||
|
[METER_VALUE_NOTICE] = A_BOLD | ColorPair(Yellow,Black),
|
||||||
|
[METER_VALUE_OK] = ColorPair(Green,Black),
|
||||||
[LED_COLOR] = ColorPair(Green,Black),
|
[LED_COLOR] = ColorPair(Green,Black),
|
||||||
[TASKS_RUNNING] = A_BOLD | ColorPair(Green,Black),
|
[TASKS_RUNNING] = A_BOLD | ColorPair(Green,Black),
|
||||||
[PROCESS] = ColorPair(Cyan,Black),
|
[PROCESS] = ColorPair(Cyan,Black),
|
||||||
|
|
3
CRT.h
3
CRT.h
|
@ -53,9 +53,10 @@ typedef enum ColorElements_ {
|
||||||
METER_TEXT,
|
METER_TEXT,
|
||||||
METER_VALUE,
|
METER_VALUE,
|
||||||
METER_VALUE_ERROR,
|
METER_VALUE_ERROR,
|
||||||
METER_VALUE_NOTICE,
|
|
||||||
METER_VALUE_IOREAD,
|
METER_VALUE_IOREAD,
|
||||||
METER_VALUE_IOWRITE,
|
METER_VALUE_IOWRITE,
|
||||||
|
METER_VALUE_NOTICE,
|
||||||
|
METER_VALUE_OK,
|
||||||
LED_COLOR,
|
LED_COLOR,
|
||||||
UPTIME,
|
UPTIME,
|
||||||
BATTERY,
|
BATTERY,
|
||||||
|
|
|
@ -130,6 +130,7 @@ linux_platform_headers = \
|
||||||
linux/Platform.h \
|
linux/Platform.h \
|
||||||
linux/PressureStallMeter.h \
|
linux/PressureStallMeter.h \
|
||||||
linux/SELinuxMeter.h \
|
linux/SELinuxMeter.h \
|
||||||
|
linux/SystemdMeter.h \
|
||||||
linux/ZramMeter.h \
|
linux/ZramMeter.h \
|
||||||
linux/ZramStats.h \
|
linux/ZramStats.h \
|
||||||
zfs/ZfsArcMeter.h \
|
zfs/ZfsArcMeter.h \
|
||||||
|
@ -146,6 +147,7 @@ myhtopplatsources = \
|
||||||
linux/Platform.c \
|
linux/Platform.c \
|
||||||
linux/PressureStallMeter.c \
|
linux/PressureStallMeter.c \
|
||||||
linux/SELinuxMeter.c \
|
linux/SELinuxMeter.c \
|
||||||
|
linux/SystemdMeter.c \
|
||||||
linux/ZramMeter.c \
|
linux/ZramMeter.c \
|
||||||
zfs/ZfsArcMeter.c \
|
zfs/ZfsArcMeter.c \
|
||||||
zfs/ZfsArcStats.c \
|
zfs/ZfsArcStats.c \
|
||||||
|
|
|
@ -90,6 +90,8 @@ AC_FUNC_CLOSEDIR_VOID
|
||||||
AC_FUNC_STAT
|
AC_FUNC_STAT
|
||||||
AC_CHECK_FUNCS([fstatat memmove strncasecmp strstr strdup])
|
AC_CHECK_FUNCS([fstatat memmove strncasecmp strstr strdup])
|
||||||
|
|
||||||
|
AC_SEARCH_LIBS([dlopen], [dl dld])
|
||||||
|
|
||||||
save_cflags="${CFLAGS}"
|
save_cflags="${CFLAGS}"
|
||||||
CFLAGS="${CFLAGS} -std=c99"
|
CFLAGS="${CFLAGS} -std=c99"
|
||||||
AC_MSG_CHECKING([whether cc -std=c99 option works])
|
AC_MSG_CHECKING([whether cc -std=c99 option works])
|
||||||
|
|
|
@ -39,6 +39,7 @@ in the source distribution for its full text.
|
||||||
#include "SELinuxMeter.h"
|
#include "SELinuxMeter.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "SwapMeter.h"
|
#include "SwapMeter.h"
|
||||||
|
#include "SystemdMeter.h"
|
||||||
#include "TasksMeter.h"
|
#include "TasksMeter.h"
|
||||||
#include "UptimeMeter.h"
|
#include "UptimeMeter.h"
|
||||||
#include "XUtils.h"
|
#include "XUtils.h"
|
||||||
|
@ -153,6 +154,7 @@ const MeterClass* const Platform_meterTypes[] = {
|
||||||
&DiskIOMeter_class,
|
&DiskIOMeter_class,
|
||||||
&NetworkIOMeter_class,
|
&NetworkIOMeter_class,
|
||||||
&SELinuxMeter_class,
|
&SELinuxMeter_class,
|
||||||
|
&SystemdMeter_class,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,329 @@
|
||||||
|
/*
|
||||||
|
htop - SystemdMeter.c
|
||||||
|
(C) 2020 Christian Göttsche
|
||||||
|
Released under the GNU GPLv2, see the COPYING file
|
||||||
|
in the source distribution for its full text.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SystemdMeter.h"
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include "CRT.h"
|
||||||
|
#include "XUtils.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define INVALID_VALUE ((unsigned int)-1)
|
||||||
|
|
||||||
|
typedef void sd_bus;
|
||||||
|
typedef void sd_bus_error;
|
||||||
|
static int (*sym_sd_bus_open_system)(sd_bus**);
|
||||||
|
static int (*sym_sd_bus_get_property_string)(sd_bus*, const char*, const char*, const char*, const char*, sd_bus_error*, char**);
|
||||||
|
static int (*sym_sd_bus_get_property_trivial)(sd_bus*, const char*, const char*, const char*, const char*, sd_bus_error*, char, void*);
|
||||||
|
static sd_bus* (*sym_sd_bus_unref)(sd_bus*);
|
||||||
|
|
||||||
|
static char* systemState = NULL;
|
||||||
|
static unsigned int nFailedUnits = INVALID_VALUE;
|
||||||
|
static unsigned int nInstalledJobs = INVALID_VALUE;
|
||||||
|
static unsigned int nNames = INVALID_VALUE;
|
||||||
|
static unsigned int nJobs = INVALID_VALUE;
|
||||||
|
static void* dlopenHandle = NULL;
|
||||||
|
static sd_bus* bus = NULL;
|
||||||
|
|
||||||
|
static void SystemdMeter_done(ATTR_UNUSED Meter* this) {
|
||||||
|
free(systemState);
|
||||||
|
systemState = NULL;
|
||||||
|
|
||||||
|
if (bus && dlopenHandle) {
|
||||||
|
sym_sd_bus_unref(bus);
|
||||||
|
}
|
||||||
|
bus = NULL;
|
||||||
|
|
||||||
|
if (dlopenHandle) {
|
||||||
|
dlclose(dlopenHandle);
|
||||||
|
dlopenHandle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int updateViaLib(void) {
|
||||||
|
if (!dlopenHandle) {
|
||||||
|
dlopenHandle = dlopen("libsystemd.so.0", RTLD_LAZY);
|
||||||
|
if (!dlopenHandle)
|
||||||
|
goto dlfailure;
|
||||||
|
|
||||||
|
/* Clear any errors */
|
||||||
|
dlerror();
|
||||||
|
|
||||||
|
#define resolve(symbolname) do { \
|
||||||
|
*(void **)(&sym_##symbolname) = dlsym(dlopenHandle, #symbolname); \
|
||||||
|
if (!sym_##symbolname || dlerror() != NULL) \
|
||||||
|
goto dlfailure; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
resolve(sd_bus_open_system);
|
||||||
|
resolve(sd_bus_get_property_string);
|
||||||
|
resolve(sd_bus_get_property_trivial);
|
||||||
|
resolve(sd_bus_unref);
|
||||||
|
|
||||||
|
#undef resolve
|
||||||
|
}
|
||||||
|
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* Connect to the system bus */
|
||||||
|
if (!bus) {
|
||||||
|
r = sym_sd_bus_open_system(&bus);
|
||||||
|
if (r < 0)
|
||||||
|
goto busfailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* const busServiceName = "org.freedesktop.systemd1";
|
||||||
|
static const char* const busObjectPath = "/org/freedesktop/systemd1";
|
||||||
|
static const char* const busInterfaceName = "org.freedesktop.systemd1.Manager";
|
||||||
|
|
||||||
|
r = sym_sd_bus_get_property_string(bus,
|
||||||
|
busServiceName, /* service to contact */
|
||||||
|
busObjectPath, /* object path */
|
||||||
|
busInterfaceName, /* interface name */
|
||||||
|
"SystemState", /* property name */
|
||||||
|
NULL, /* object to return error in */
|
||||||
|
&systemState);
|
||||||
|
if (r < 0)
|
||||||
|
goto busfailure;
|
||||||
|
|
||||||
|
r = sym_sd_bus_get_property_trivial(bus,
|
||||||
|
busServiceName, /* service to contact */
|
||||||
|
busObjectPath, /* object path */
|
||||||
|
busInterfaceName, /* interface name */
|
||||||
|
"NFailedUnits", /* property name */
|
||||||
|
NULL, /* object to return error in */
|
||||||
|
'u', /* property type */
|
||||||
|
&nFailedUnits);
|
||||||
|
if (r < 0)
|
||||||
|
goto busfailure;
|
||||||
|
|
||||||
|
r = sym_sd_bus_get_property_trivial(bus,
|
||||||
|
busServiceName, /* service to contact */
|
||||||
|
busObjectPath, /* object path */
|
||||||
|
busInterfaceName, /* interface name */
|
||||||
|
"NInstalledJobs", /* property name */
|
||||||
|
NULL, /* object to return error in */
|
||||||
|
'u', /* property type */
|
||||||
|
&nInstalledJobs);
|
||||||
|
if (r < 0)
|
||||||
|
goto busfailure;
|
||||||
|
|
||||||
|
r = sym_sd_bus_get_property_trivial(bus,
|
||||||
|
busServiceName, /* service to contact */
|
||||||
|
busObjectPath, /* object path */
|
||||||
|
busInterfaceName, /* interface name */
|
||||||
|
"NNames", /* property name */
|
||||||
|
NULL, /* object to return error in */
|
||||||
|
'u', /* property type */
|
||||||
|
&nNames);
|
||||||
|
if (r < 0)
|
||||||
|
goto busfailure;
|
||||||
|
|
||||||
|
r = sym_sd_bus_get_property_trivial(bus,
|
||||||
|
busServiceName, /* service to contact */
|
||||||
|
busObjectPath, /* object path */
|
||||||
|
busInterfaceName, /* interface name */
|
||||||
|
"NJobs", /* property name */
|
||||||
|
NULL, /* object to return error in */
|
||||||
|
'u', /* property type */
|
||||||
|
&nJobs);
|
||||||
|
if (r < 0)
|
||||||
|
goto busfailure;
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
busfailure:
|
||||||
|
sym_sd_bus_unref(bus);
|
||||||
|
bus = NULL;
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
dlfailure:
|
||||||
|
if (dlopenHandle) {
|
||||||
|
dlclose(dlopenHandle);
|
||||||
|
dlopenHandle = NULL;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateViaExec(void) {
|
||||||
|
int fdpair[2];
|
||||||
|
if (pipe(fdpair) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pid_t child = fork();
|
||||||
|
if (child < 0) {
|
||||||
|
close(fdpair[1]);
|
||||||
|
close(fdpair[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child == 0) {
|
||||||
|
close(fdpair[0]);
|
||||||
|
dup2(fdpair[1], STDOUT_FILENO);
|
||||||
|
close(fdpair[1]);
|
||||||
|
int fdnull = open("/dev/null", O_WRONLY);
|
||||||
|
if (fdnull < 0)
|
||||||
|
exit(1);
|
||||||
|
dup2(fdnull, STDERR_FILENO);
|
||||||
|
close(fdnull);
|
||||||
|
execl("/bin/systemctl",
|
||||||
|
"/bin/systemctl",
|
||||||
|
"show",
|
||||||
|
"--property=SystemState",
|
||||||
|
"--property=NFailedUnits",
|
||||||
|
"--property=NNames",
|
||||||
|
"--property=NJobs",
|
||||||
|
"--property=NInstalledJobs",
|
||||||
|
NULL);
|
||||||
|
exit(127);
|
||||||
|
}
|
||||||
|
close(fdpair[1]);
|
||||||
|
|
||||||
|
int wstatus;
|
||||||
|
if (waitpid(child, &wstatus, 0) < 0 || !WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
|
||||||
|
close(fdpair[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* commandOutput = fdopen(fdpair[0], "r");
|
||||||
|
if (!commandOutput) {
|
||||||
|
close(fdpair[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char lineBuffer[128];
|
||||||
|
while (fgets(lineBuffer, sizeof(lineBuffer), commandOutput)) {
|
||||||
|
if (String_startsWith(lineBuffer, "SystemState=")) {
|
||||||
|
char* newline = strchr(lineBuffer + strlen("SystemState="), '\n');
|
||||||
|
if (newline)
|
||||||
|
*newline = '\0';
|
||||||
|
systemState = xStrdup(lineBuffer + strlen("SystemState="));
|
||||||
|
} else if (String_startsWith(lineBuffer, "NFailedUnits=")) {
|
||||||
|
nFailedUnits = strtoul(lineBuffer + strlen("NFailedUnits="), NULL, 10);
|
||||||
|
} else if (String_startsWith(lineBuffer, "NNames=")) {
|
||||||
|
nNames = strtoul(lineBuffer + strlen("NNames="), NULL, 10);
|
||||||
|
} else if (String_startsWith(lineBuffer, "NJobs=")) {
|
||||||
|
nJobs = strtoul(lineBuffer + strlen("NJobs="), NULL, 10);
|
||||||
|
} else if (String_startsWith(lineBuffer, "NInstalledJobs=")) {
|
||||||
|
nInstalledJobs = strtoul(lineBuffer + strlen("NInstalledJobs="), NULL, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(commandOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SystemdMeter_updateValues(ATTR_UNUSED Meter* this, char* buffer, int size) {
|
||||||
|
free(systemState);
|
||||||
|
systemState = NULL;
|
||||||
|
nFailedUnits = nInstalledJobs = nNames = nJobs = INVALID_VALUE;
|
||||||
|
|
||||||
|
if (updateViaLib() < 0)
|
||||||
|
updateViaExec();
|
||||||
|
|
||||||
|
xSnprintf(buffer, size, "%s", systemState ? systemState : "???");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zeroDigitColor(unsigned int value) {
|
||||||
|
switch (value) {
|
||||||
|
case 0:
|
||||||
|
return CRT_colors[METER_VALUE];
|
||||||
|
case INVALID_VALUE:
|
||||||
|
return CRT_colors[METER_VALUE_ERROR];
|
||||||
|
default:
|
||||||
|
return CRT_colors[METER_VALUE_NOTICE];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int valueDigitColor(unsigned int value) {
|
||||||
|
switch (value) {
|
||||||
|
case 0:
|
||||||
|
return CRT_colors[METER_VALUE_NOTICE];
|
||||||
|
case INVALID_VALUE:
|
||||||
|
return CRT_colors[METER_VALUE_ERROR];
|
||||||
|
default:
|
||||||
|
return CRT_colors[METER_VALUE];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void SystemdMeter_display(ATTR_UNUSED const Object* cast, RichString* out) {
|
||||||
|
char buffer[16];
|
||||||
|
|
||||||
|
int color = (systemState && 0 == strcmp(systemState, "running")) ? METER_VALUE_OK : METER_VALUE_ERROR;
|
||||||
|
RichString_write(out, CRT_colors[color], systemState ? systemState : "???");
|
||||||
|
|
||||||
|
RichString_append(out, CRT_colors[METER_TEXT], " (");
|
||||||
|
|
||||||
|
if (nFailedUnits == INVALID_VALUE) {
|
||||||
|
buffer[0] = '?';
|
||||||
|
buffer[1] = '\0';
|
||||||
|
} else {
|
||||||
|
xSnprintf(buffer, sizeof(buffer), "%u", nFailedUnits);
|
||||||
|
}
|
||||||
|
RichString_append(out, zeroDigitColor(nFailedUnits), buffer);
|
||||||
|
|
||||||
|
RichString_append(out, CRT_colors[METER_TEXT], "/");
|
||||||
|
|
||||||
|
if (nNames == INVALID_VALUE) {
|
||||||
|
buffer[0] = '?';
|
||||||
|
buffer[1] = '\0';
|
||||||
|
} else {
|
||||||
|
xSnprintf(buffer, sizeof(buffer), "%u", nNames);
|
||||||
|
}
|
||||||
|
RichString_append(out, valueDigitColor(nNames), buffer);
|
||||||
|
|
||||||
|
RichString_append(out, CRT_colors[METER_TEXT], " failed) (");
|
||||||
|
|
||||||
|
if (nJobs == INVALID_VALUE) {
|
||||||
|
buffer[0] = '?';
|
||||||
|
buffer[1] = '\0';
|
||||||
|
} else {
|
||||||
|
xSnprintf(buffer, sizeof(buffer), "%u", nJobs);
|
||||||
|
}
|
||||||
|
RichString_append(out, zeroDigitColor(nJobs), buffer);
|
||||||
|
|
||||||
|
RichString_append(out, CRT_colors[METER_TEXT], "/");
|
||||||
|
|
||||||
|
if (nInstalledJobs == INVALID_VALUE) {
|
||||||
|
buffer[0] = '?';
|
||||||
|
buffer[1] = '\0';
|
||||||
|
} else {
|
||||||
|
xSnprintf(buffer, sizeof(buffer), "%u", nInstalledJobs);
|
||||||
|
}
|
||||||
|
RichString_append(out, valueDigitColor(nInstalledJobs), buffer);
|
||||||
|
|
||||||
|
RichString_append(out, CRT_colors[METER_TEXT], " jobs)");
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int SystemdMeter_attributes[] = {
|
||||||
|
METER_VALUE
|
||||||
|
};
|
||||||
|
|
||||||
|
const MeterClass SystemdMeter_class = {
|
||||||
|
.super = {
|
||||||
|
.extends = Class(Meter),
|
||||||
|
.delete = Meter_delete,
|
||||||
|
.display = SystemdMeter_display
|
||||||
|
},
|
||||||
|
.updateValues = SystemdMeter_updateValues,
|
||||||
|
.done = SystemdMeter_done,
|
||||||
|
.defaultMode = TEXT_METERMODE,
|
||||||
|
.maxItems = 0,
|
||||||
|
.total = 100.0,
|
||||||
|
.attributes = SystemdMeter_attributes,
|
||||||
|
.name = "Systemd",
|
||||||
|
.uiName = "Systemd state",
|
||||||
|
.description = "Systemd system state and unit overview",
|
||||||
|
.caption = "Systemd: ",
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef HEADER_SystemdMeter
|
||||||
|
#define HEADER_SystemdMeter
|
||||||
|
|
||||||
|
/*
|
||||||
|
htop - SystemdMeter.h
|
||||||
|
(C) 2020 Christian Göttsche
|
||||||
|
Released under the GNU GPLv2, see the COPYING file
|
||||||
|
in the source distribution for its full text.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Meter.h"
|
||||||
|
|
||||||
|
extern const MeterClass SystemdMeter_class;
|
||||||
|
|
||||||
|
#endif /* HEADER_SystemdMeter */
|
Loading…
Reference in New Issue