summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornia <nia@NetBSD.org>2021-07-26 19:04:44 +0200
committerBenBE <BenBE@geshi.org>2021-08-05 10:47:14 +0200
commitfdcdc54ec45d4512ec8ad9524362e808d1928569 (patch)
tree5910483330411c26b8cfe7ca1654a2cd9a1265f5
parent2e3f34f5c1f7cff7621fa453e2315b3af62554e7 (diff)
netbsd: Add battery support
This uses proplib and sysmon_envsys to determine the total charge percentage of any number of connected batteries as well as the AC adapter state. Should work with ACPI and non-ACPI systems.
-rw-r--r--configure.ac1
-rw-r--r--netbsd/Platform.c106
-rw-r--r--netbsd/README.md1
3 files changed, 104 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac
index 1c83c28e..99915cce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -216,6 +216,7 @@ fi
if test "$my_htop_platform" = netbsd; then
AC_SEARCH_LIBS([kvm_open], [kvm], [], [AC_MSG_ERROR([can not find required function kvm_open()])])
+ AC_SEARCH_LIBS([prop_dictionary_get], [prop], [], [AC_MSG_ERROR([can not find required function prop_dictionary_get()])])
fi
if test "$my_htop_platform" = openbsd; then
diff --git a/netbsd/Platform.c b/netbsd/Platform.c
index d3840ad1..d26c29cb 100644
--- a/netbsd/Platform.c
+++ b/netbsd/Platform.c
@@ -3,6 +3,7 @@ htop - netbsd/Platform.c
(C) 2014 Hisham H. Muhammad
(C) 2015 Michael McConville
(C) 2021 Santhosh Raju
+(C) 2021 Nia Alarie
(C) 2021 htop dev team
Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
@@ -11,12 +12,18 @@ in the source distribution for its full text.
#include "netbsd/Platform.h"
#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <unistd.h>
#include <kvm.h>
#include <limits.h>
#include <math.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <prop/proplib.h>
+#include <sys/envsys.h>
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <sys/time.h>
@@ -323,7 +330,100 @@ bool Platform_getNetworkIO(NetworkIOData* data) {
}
void Platform_getBattery(double* percent, ACPresence* isOnAC) {
- // TODO
- (void)percent;
- (void)isOnAC;
+ int fd;
+ bool isACAD, isBattery;
+ int64_t isPresent, isConnected;
+ int64_t curCharge, maxCharge;
+ int64_t totalCharge, totalCapacity;
+ prop_dictionary_t dict, fields, props;
+ prop_object_iterator_t devIter, fieldsIter;
+ prop_object_t device, class, fieldsArray, curValue, maxValue, descField;
+
+ totalCharge = 0;
+ totalCapacity = 0;
+
+ *percent = NAN;
+ *isOnAC = AC_ERROR;
+
+ fd = open(_PATH_SYSMON, O_RDONLY);
+ if (fd == -1)
+ goto error;
+
+ if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &dict) != 0)
+ goto error;
+
+ devIter = prop_dictionary_iterator(dict);
+ if (devIter == NULL)
+ goto error;
+
+ while ((device = prop_object_iterator_next(devIter)) != NULL) {
+ fieldsArray = prop_dictionary_get_keysym(dict, device);
+ if (fieldsArray == NULL)
+ goto error;
+
+ fieldsIter = prop_array_iterator(fieldsArray);
+ if (fieldsIter == NULL)
+ goto error;
+
+ isACAD = false;
+ isBattery = false;
+
+ /* only assume battery is not present if explicitly stated */
+ isPresent = 1;
+ isConnected = 0;
+ curCharge = 0;
+ maxCharge = 0;
+
+ while ((fields = prop_object_iterator_next(fieldsIter)) != NULL) {
+ props = prop_dictionary_get(fields, "device-properties");
+ if (props != NULL) {
+ class = prop_dictionary_get(props, "device-class");
+
+ /*
+ * After NetBSD 11's release NetBSD 9 will no longer be supported
+ * and these should be converted to prop_string_equals_string.
+ */
+
+ if (prop_string_equals_cstring(class, "ac-adapter")) {
+ isACAD = true;
+ } else if (prop_string_equals_cstring(class, "battery")) {
+ isBattery = true;
+ }
+ continue;
+ }
+
+ curValue = prop_dictionary_get(fields, "cur-value");
+ maxValue = prop_dictionary_get(fields, "max-value");
+ descField = prop_dictionary_get(fields, "description");
+
+ if (descField == NULL || curValue == NULL)
+ continue;
+
+ if (prop_string_equals_cstring(descField, "connected")) {
+ isConnected = prop_number_integer_value(curValue);
+ } else if (prop_string_equals_cstring(descField, "present")) {
+ isPresent = prop_number_integer_value(curValue);
+ } else if (prop_string_equals_cstring(descField, "charge")) {
+ if (maxValue == NULL)
+ continue;
+ curCharge = prop_number_integer_value(curValue);
+ maxCharge = prop_number_integer_value(maxValue);
+ }
+ }
+
+ if (isBattery && isPresent) {
+ totalCharge += curCharge;
+ totalCapacity += maxCharge;
+ }
+
+ if (isACAD) {
+ *isOnAC = isConnected ? AC_PRESENT : AC_ABSENT;
+ }
+ }
+
+ *percent = ((double)totalCharge / (double)totalCapacity) * 100.0;
+
+error:
+ if (fd != -1)
+ close(fd);
}
diff --git a/netbsd/README.md b/netbsd/README.md
index 1d13e76e..ed7be0a3 100644
--- a/netbsd/README.md
+++ b/netbsd/README.md
@@ -27,7 +27,6 @@ What needs improvement
* Kernel and userspace threads are not displayed or counted -
maybe look at NetBSD top(1).
-* Battery display - use envsys(4).
* Support for compiling using libcurses's Unicode support.
* Support for fstat(1) (view open files, like lsof(8) on Linux).
* Support for ktrace(1) (like strace(1) on Linux).

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