summaryrefslogtreecommitdiffstats
path: root/linux/LibSensors.c
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 /linux/LibSensors.c
parentf7a89529330044f4e2a38e85a88ec90f839ae64e (diff)
Dynamically load libsensors at runtime
Diffstat (limited to 'linux/LibSensors.c')
-rw-r--r--linux/LibSensors.c105
1 files changed, 105 insertions, 0 deletions
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 */

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