summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Göttsche <cgzones@googlemail.com>2020-12-01 13:59:19 +0100
committerBenBE <BenBE@geshi.org>2020-12-02 21:03:24 +0100
commitb76eaf187a313c99fe008b069b8123b299752589 (patch)
tree54bc2656cbc1fba7b75cf7bd823f4f0af42d7673
parentf7a89529330044f4e2a38e85a88ec90f839ae64e (diff)
Dynamically load libsensors at runtime
-rw-r--r--CPUMeter.c4
-rw-r--r--DisplayOptionsPanel.c4
-rw-r--r--Makefile.am2
-rw-r--r--Settings.c6
-rw-r--r--Settings.h2
-rw-r--r--configure.ac4
-rw-r--r--linux/LibSensors.c105
-rw-r--r--linux/LibSensors.h16
-rw-r--r--linux/LinuxProcessList.c46
-rw-r--r--linux/LinuxProcessList.h2
-rw-r--r--linux/Platform.c15
11 files changed, 147 insertions, 59 deletions
diff --git a/CPUMeter.c b/CPUMeter.c
index 61b33cb6..855d94bd 100644
--- a/CPUMeter.c
+++ b/CPUMeter.c
@@ -79,7 +79,7 @@ static void CPUMeter_updateValues(Meter* this, char* buffer, int size) {
}
}
- #ifdef HAVE_LIBSENSORS
+ #ifdef HAVE_SENSORS_SENSORS_H
if (this->pl->settings->showCPUTemperature) {
double cpuTemperature = this->values[CPU_METER_TEMPERATURE];
if (isnan(cpuTemperature))
@@ -150,7 +150,7 @@ static void CPUMeter_display(const Object* cast, RichString* out) {
}
}
- #ifdef HAVE_LIBSENSORS
+ #ifdef HAVE_SENSORS_SENSORS_H
if (this->pl->settings->showCPUTemperature) {
char cpuTemperatureBuffer[10];
double cpuTemperature = this->values[CPU_METER_TEMPERATURE];
diff --git a/DisplayOptionsPanel.c b/DisplayOptionsPanel.c
index bf3fa584..e0d4cfd8 100644
--- a/DisplayOptionsPanel.c
+++ b/DisplayOptionsPanel.c
@@ -116,8 +116,8 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
Panel_add(super, (Object*) CheckItem_newByRef("Add guest time in CPU meter percentage", &(settings->accountGuestInCPUMeter)));
Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU percentage numerically", &(settings->showCPUUsage)));
Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU frequency", &(settings->showCPUFrequency)));
- #ifdef HAVE_LIBSENSORS
- Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU temperature", &(settings->showCPUTemperature)));
+ #ifdef HAVE_SENSORS_SENSORS_H
+ Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU temperature (requires libsensors)", &(settings->showCPUTemperature)));
Panel_add(super, (Object*) CheckItem_newByRef("- Show temperature in degree Fahrenheit instead of Celsius", &(settings->degreeFahrenheit)));
#endif
Panel_add(super, (Object*) CheckItem_newByRef("Enable the mouse", &(settings->enableMouse)));
diff --git a/Makefile.am b/Makefile.am
index 194783fa..6ef020c4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -126,6 +126,7 @@ myhtopheaders = \
linux_platform_headers = \
linux/IOPriority.h \
linux/IOPriorityPanel.h \
+ linux/LibSensors.h \
linux/LinuxProcess.h \
linux/LinuxProcessList.h \
linux/Platform.h \
@@ -142,6 +143,7 @@ if HTOP_LINUX
AM_LDFLAGS += -rdynamic
myhtopplatsources = \
linux/IOPriorityPanel.c \
+ linux/LibSensors.c \
linux/LinuxProcess.c \
linux/LinuxProcessList.c \
linux/Platform.c \
diff --git a/Settings.c b/Settings.c
index f2019e9a..0b4d0ed6 100644
--- a/Settings.c
+++ b/Settings.c
@@ -183,7 +183,7 @@ static bool Settings_read(Settings* this, const char* fileName, int initialCpuCo
this->showCPUUsage = atoi(option[1]);
} else if (String_eq(option[0], "show_cpu_frequency")) {
this->showCPUFrequency = atoi(option[1]);
- #ifdef HAVE_LIBSENSORS
+ #ifdef HAVE_SENSORS_SENSORS_H
} else if (String_eq(option[0], "show_cpu_temperature")) {
this->showCPUTemperature = atoi(option[1]);
} else if (String_eq(option[0], "degree_fahrenheit")) {
@@ -292,7 +292,7 @@ bool Settings_write(Settings* this) {
fprintf(fd, "cpu_count_from_one=%d\n", (int) this->countCPUsFromOne);
fprintf(fd, "show_cpu_usage=%d\n", (int) this->showCPUUsage);
fprintf(fd, "show_cpu_frequency=%d\n", (int) this->showCPUFrequency);
- #ifdef HAVE_LIBSENSORS
+ #ifdef HAVE_SENSORS_SENSORS_H
fprintf(fd, "show_cpu_temperature=%d\n", (int) this->showCPUTemperature);
fprintf(fd, "degree_fahrenheit=%d\n", (int) this->degreeFahrenheit);
#endif
@@ -328,7 +328,7 @@ Settings* Settings_new(int initialCpuCount) {
this->countCPUsFromOne = false;
this->showCPUUsage = true;
this->showCPUFrequency = false;
- #ifdef HAVE_LIBSENSORS
+ #ifdef HAVE_SENSORS_SENSORS_H
this->showCPUTemperature = false;
this->degreeFahrenheit = false;
#endif
diff --git a/Settings.h b/Settings.h
index b01ce23f..dab531f7 100644
--- a/Settings.h
+++ b/Settings.h
@@ -38,7 +38,7 @@ typedef struct Settings_ {
bool detailedCPUTime;
bool showCPUUsage;
bool showCPUFrequency;
- #ifdef HAVE_LIBSENSORS
+ #ifdef HAVE_SENSORS_SENSORS_H
bool showCPUTemperature;
bool degreeFahrenheit;
#endif
diff --git a/configure.ac b/configure.ac
index edf7f366..30b2502b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -307,13 +307,11 @@ then
])
fi
-AC_ARG_ENABLE(sensors, [AS_HELP_STRING([--enable-sensors], [enable libsensors support for reading temperature data.])],, enable_sensors="check")
+AC_ARG_ENABLE(sensors, [AS_HELP_STRING([--with-sensors], [Compile with libsensors support for reading temperature data. Only requires libsensors headers at compile time, at runtime libsensors is loaded via dlopen.])],, enable_sensors="check")
if test "x$enable_sensors" = xyes; then
- AC_CHECK_LIB([sensors], [sensors_get_value], [], [missing_libraries="$missing_libraries libsensors"])
AC_CHECK_HEADERS([sensors/sensors.h], [], [missing_headers="$missing_headers $ac_header"])
elif test "x$enable_sensors" = xcheck; then
enable_sensors=yes
- AC_CHECK_LIB([sensors], [sensors_get_value], [], [enable_sensors=no])
AC_CHECK_HEADERS([sensors/sensors.h], [], [enable_sensors=no])
fi
diff --git a/linux/LibSensors.c b/linux/LibSensors.c
new file mode 100644
index 00000000..1f3bd8de
--- /dev/null
+++ b/linux/LibSensors.c
@@ -0,0 +1,105 @@
+#include "LibSensors.h"
+
+#ifdef HAVE_SENSORS_SENSORS_H
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <limits.h>
+#include <sensors/sensors.h>
+
+#include "XUtils.h"
+
+
+static int (*sym_sensors_init)(FILE*);
+static void (*sym_sensors_cleanup)(void);
+static const sensors_chip_name* (*sym_sensors_get_detected_chips)(const sensors_chip_name*, int*);
+static int (*sym_sensors_snprintf_chip_name)(char*, size_t, const sensors_chip_name*);
+static const sensors_feature* (*sym_sensors_get_features)(const sensors_chip_name*, int*);
+static const sensors_subfeature* (*sym_sensors_get_subfeature)(const sensors_chip_name*, const sensors_feature*, sensors_subfeature_type);
+static int (*sym_sensors_get_value)(const sensors_chip_name*, int, double*);
+
+static void* dlopenHandle = NULL;
+
+int LibSensors_init(FILE* input) {
+ if (!dlopenHandle) {
+ dlopenHandle = dlopen("libsensors.so", 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(sensors_init);
+ resolve(sensors_cleanup);
+ resolve(sensors_get_detected_chips);
+ resolve(sensors_snprintf_chip_name);
+ resolve(sensors_get_features);
+ resolve(sensors_get_subfeature);
+ resolve(sensors_get_value);
+
+ #undef resolve
+ }
+
+ return sym_sensors_init(input);
+
+dlfailure:
+ if (dlopenHandle) {
+ dlclose(dlopenHandle);
+ dlopenHandle = NULL;
+ }
+ return -1;
+}
+
+void LibSensors_cleanup(void) {
+ if (dlopenHandle) {
+ sym_sensors_cleanup();
+
+ dlclose(dlopenHandle);
+ dlopenHandle = NULL;
+ }
+}
+
+int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount) {
+ if (!dlopenHandle)
+ return -ENOTSUP;
+
+ int tempCount = 0;
+
+ int n = 0;
+ for (const sensors_chip_name *chip = sym_sensors_get_detected_chips(NULL, &n); chip; chip = sym_sensors_get_detected_chips(NULL, &n)) {
+ char buffer[32];
+ sym_sensors_snprintf_chip_name(buffer, sizeof(buffer), chip);
+ if (!String_startsWith(buffer, "coretemp") && !String_startsWith(buffer, "cpu_thermal"))
+ continue;
+
+ int m = 0;
+ for (const sensors_feature *feature = sym_sensors_get_features(chip, &m); feature; feature = sym_sensors_get_features(chip, &m)) {
+ if (feature->type != SENSORS_FEATURE_TEMP)
+ continue;
+
+ if (feature->number > cpuCount)
+ continue;
+
+ const sensors_subfeature *sub_feature = sym_sensors_get_subfeature(chip, feature, SENSORS_SUBFEATURE_TEMP_INPUT);
+ if (sub_feature) {
+ double temp;
+ int r = sym_sensors_get_value(chip, sub_feature->number, &temp);
+ if (r != 0)
+ continue;
+
+ cpus[feature->number].temperature = temp;
+ tempCount++;
+ }
+ }
+ }
+
+ return tempCount;
+}
+
+#endif /* HAVE_SENSORS_SENSORS_H */
diff --git a/linux/LibSensors.h b/linux/LibSensors.h
new file mode 100644
index 00000000..ed9be7b0
--- /dev/null
+++ b/linux/LibSensors.h
@@ -0,0 +1,16 @@
+#ifndef HEADER_LibSensors
+#define HEADER_LibSensors
+
+#include "config.h" // IWYU pragma: keep
+
+#include <stdio.h>
+
+#include "LinuxProcessList.h"
+
+
+int LibSensors_init(FILE* input);
+void LibSensors_cleanup(void);
+
+int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount);
+
+#endif /* HEADER_LibSensors */
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index fd8f5aff..5d9ec87b 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -53,8 +53,8 @@ in the source distribution for its full text.
#include <sys/sysmacros.h>
#endif
-#ifdef HAVE_LIBSENSORS
-#include <sensors/sensors.h>
+#ifdef HAVE_SENSORS_SENSORS_H
+#include "LibSensors.h"
#endif
@@ -1794,41 +1794,7 @@ static void LinuxProcessList_scanCPUFrequency(LinuxProcessList* this) {
scanCPUFreqencyFromCPUinfo(this);
}
-#ifdef HAVE_LIBSENSORS
-static int getCPUTemperatures(CPUData* cpus, int cpuCount) {
- int tempCount = 0;
-
- int n = 0;
- for (const sensors_chip_name *chip = sensors_get_detected_chips(NULL, &n); chip; chip = sensors_get_detected_chips(NULL, &n)) {
- char buffer[32];
- sensors_snprintf_chip_name(buffer, sizeof(buffer), chip);
- if (!String_startsWith(buffer, "coretemp") && !String_startsWith(buffer, "cpu_thermal"))
- continue;
-
- int m = 0;
- for (const sensors_feature *feature = sensors_get_features(chip, &m); feature; feature = sensors_get_features(chip, &m)) {
- if (feature->type != SENSORS_FEATURE_TEMP)
- continue;
-
- if (feature->number > cpuCount)
- continue;
-
- const sensors_subfeature *sub_feature = sensors_get_subfeature(chip, feature, SENSORS_SUBFEATURE_TEMP_INPUT);
- if (sub_feature) {
- double temp;
- int r = sensors_get_value(chip, sub_feature->number, &temp);
- if (r != 0)
- continue;
-
- cpus[feature->number].temperature = temp;
- tempCount++;
- }
- }
- }
-
- return tempCount;
-}
-
+#ifdef HAVE_SENSORS_SENSORS_H
static void LinuxProcessList_scanCPUTemperature(LinuxProcessList* this) {
const int cpuCount = this->super.cpuCount;
@@ -1836,10 +1802,10 @@ static void LinuxProcessList_scanCPUTemperature(LinuxProcessList* this) {
this->cpus[i].temperature = NAN;
}
- int r = getCPUTemperatures(this->cpus, cpuCount);
+ int r = LibSensors_getCPUTemperatures(this->cpus, cpuCount);
/* No temperature - nothing to do */
- if (r == 0)
+ if (r <= 0)
return;
/* Only package temperature - copy to all cpus */
@@ -1878,7 +1844,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
LinuxProcessList_scanCPUFrequency(this);
}
- #ifdef HAVE_LIBSENSORS
+ #ifdef HAVE_SENSORS_SENSORS_H
if (settings->showCPUTemperature)
LinuxProcessList_scanCPUTemperature(this);
#endif
diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h
index 6ce9d029..09b84afa 100644
--- a/linux/LinuxProcessList.h
+++ b/linux/LinuxProcessList.h
@@ -48,7 +48,7 @@ typedef struct CPUData_ {
double frequency;
- #ifdef HAVE_LIBSENSORS
+ #ifdef HAVE_SENSORS_SENSORS_H
double temperature;
#endif
} CPUData;
diff --git a/linux/Platform.c b/linux/Platform.c
index 1462f82e..833044b1 100644
--- a/linux/Platform.c
+++ b/linux/Platform.c
@@ -61,10 +61,11 @@ in the source distribution for its full text.
#include "zfs/ZfsArcStats.h"
#include "zfs/ZfsCompressedArcMeter.h"
-#ifdef HAVE_LIBSENSORS
-#include <sensors/sensors.h>
+#ifdef HAVE_SENSORS_SENSORS_H
+#include "LibSensors.h"
#endif
+
ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, (int)M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
int Platform_numberOfFields = LAST_PROCESSFIELD;
@@ -119,14 +120,14 @@ void Platform_init(void) {
exit(1);
}
-#ifdef HAVE_LIBSENSORS
- sensors_init(NULL);
+#ifdef HAVE_SENSORS_SENSORS_H
+ LibSensors_init(NULL);
#endif
}
void Platform_done(void) {
-#ifdef HAVE_LIBSENSORS
- sensors_cleanup();
+#ifdef HAVE_SENSORS_SENSORS_H
+ LibSensors_cleanup();
#endif
}
@@ -271,7 +272,7 @@ double Platform_setCPUValues(Meter* this, int cpu) {
v[CPU_METER_FREQUENCY] = cpuData->frequency;
-#ifdef HAVE_LIBSENSORS
+#ifdef HAVE_SENSORS_SENSORS_H
v[CPU_METER_TEMPERATURE] = cpuData->temperature;
#else
v[CPU_METER_TEMPERATURE] = NAN;

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