btop-git: Add support for battery stats.
authorSanthosh Raju <fox@NetBSD.org>
Thu, 29 Feb 2024 19:18:13 +0000 (20:18 +0100)
committerSanthosh Raju <fox@NetBSD.org>
Thu, 29 Feb 2024 19:18:32 +0000 (20:18 +0100)
btop-git/Makefile
btop-git/distinfo
btop-git/patches/patch-src_netbsd_btop__collect.cpp

index 2244e998809379f79dc79ad578744ae538330fcd..32e86f60b26e17b7d88d7799a8c77d81f866027d 100644 (file)
@@ -11,12 +11,11 @@ HOMEPAGE=   https://github.com/aristocratos/btop
 COMMENT=       Colorful TTY resource monitor
 LICENSE=       apache-2.0
 
-DEPENDS+=      coreutils-[0-9]*:../../sysutils/coreutils
-
 USE_LANGUAGES= c c++
 USE_TOOLS+=    gmake
 GCC_REQD+=     10
 CXXFLAGS+=     -DNDEBUG
+LDFLAGS.NetBSD+=-lprop
 
 MAKE_ARGS=     STRIP=true VERBOSE=true
 
index 89bff9cccd291ac53485f1b9b4384da68a1efa4f..d9b01f9c0e69450e919fcb68c15d410bb3d83d74 100644 (file)
@@ -5,4 +5,4 @@ SHA512 (btop-1.2.13.20240218-6c667402907171f3ba7ebb637e553cc6f66f4e66.tar.gz) =
 Size (btop-1.2.13.20240218-6c667402907171f3ba7ebb637e553cc6f66f4e66.tar.gz) = 1145612 bytes
 SHA1 (patch-Makefile) = c881cc9121de99902f560728da201473b2ea9ef9
 SHA1 (patch-src_btop.cpp) = 60c805d6a5343d2e46f8f7cb0b03059426871fe9
-SHA1 (patch-src_netbsd_btop__collect.cpp) = 579033f58959b83602f1591ab7b7587d83c55c75
+SHA1 (patch-src_netbsd_btop__collect.cpp) = b95700f12401cc67f23a484b8ff937ff8e2621d7
index e92931b32c7d029c1673f200535da5ad2b567051..3c25aadc58ba2844fbc1580b3eb0f14f732e404b 100644 (file)
@@ -2,9 +2,9 @@ $NetBSD$
 
 Add support for NetBSD.
 
---- src/netbsd/btop_collect.cpp.orig   2024-02-24 10:19:36.470949441 +0000
+--- src/netbsd/btop_collect.cpp.orig   2024-02-28 16:37:10.878578423 +0000
 +++ src/netbsd/btop_collect.cpp
-@@ -0,0 +1,1282 @@
+@@ -0,0 +1,1326 @@
 +/* Copyright 2021 Aristocratos (jakob@qvantnet.com)
 +
 +   Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,8 +36,10 @@ Add support for NetBSD.
 +#include <netinet/tcp_fsm.h>
 +#include <netinet/in.h> // for inet_ntop stuff
 +#include <pwd.h>
++#include <prop/proplib.h>
 +#include <sys/endian.h>
 +#include <sys/iostat.h>
++#include <sys/envsys.h>
 +#include <sys/resource.h>
 +#include <sys/socket.h>
 +#include <sys/statvfs.h>
@@ -267,40 +269,6 @@ Add support for NetBSD.
 +              return name;
 +      }
 +
-+      int64_t get_sensor(string device, int num) {
-+              int64_t temp = -1;
-+//            struct sensordev sensordev;
-+//            struct sensor sensor;
-+//            size_t sdlen, slen;
-+//            int dev;
-+//            int mib[] = {CTL_HW, HW_SENSORS, 0, 0, 0};
-+//
-+//            sdlen = sizeof(sensordev);
-+//            slen = sizeof(sensor);
-+//            for (dev = 0;; dev++) {
-+//                    mib[2] = dev;
-+//                    if (sysctl(mib, 3, &sensordev, &sdlen, NULL, 0) == -1) {
-+//                            if (errno == ENXIO)
-+//                                    continue;
-+//                            if (errno == ENOENT)
-+//                                    break;
-+//                    }
-+//                    if (strstr(sensordev.xname, device.c_str())) {
-+//                            mib[3] = type;
-+//                            mib[4] = num;
-+//                            if (sysctl(mib, 5, &sensor, &slen, NULL, 0) == -1) {
-+//                                    if (errno != ENOENT) {
-+//                                            Logger::warning("sysctl");
-+//                                            continue;
-+//                                    }
-+//                            }
-+//                            temp = sensor.value;
-+//                            break;
-+//                    }
-+//            }
-+              return temp;
-+      }
-+
 +      bool get_sensors() {
 +              got_sensors = false;
 +//            if (Config::getB("show_coretemp") and Config::getB("check_temp")) {
@@ -394,36 +362,112 @@ Add support for NetBSD.
 +      auto get_battery() -> tuple<int, float, long, string> {
 +              if (not has_battery) return {0, 0.0, 0, ""};
 +
-+              long seconds = -1;
-+              uint32_t percent = -1;
-+              string status = "discharging";
-+              int64_t full, remaining;
-+              full = get_sensor("acpibat0", 0);
-+              remaining = get_sensor("acpibat0", 3);
-+              int64_t state = get_sensor("acpibat0", 0);
-+              if (full < 0) {
++              prop_dictionary_t dict, fields, props;
++
++              int64_t totalCharge = 0;
++              int64_t totalCapacity = 0;
++
++              int fd = open(_PATH_SYSMON, O_RDONLY);
++              if (fd == -1) {
++                      Logger::warning("failed to open " + string(_PATH_SYSMON));
 +                      has_battery = false;
-+                      Logger::warning("failed to get battery");
-+              } else {
-+                      float_t f = full / 1000;
-+                      float_t r = remaining / 1000;
-+                      has_battery = true;
-+                      percent = r / f * 100;
-+                      if (percent == 100) {
-+                              status = "full";
++                      return {0, 0.0, 0, ""};
++              }
++
++              if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &dict) != 0) {
++                      if (fd != -1) {
++                              close(fd);
 +                      }
-+                      switch (state) {
-+                              case 0:
-+                                      status = "full";
-+                                      percent = 100;
-+                                      break;
-+                              case 2:
-+                                      status = "charging";
-+                                      break;
++                      has_battery = false;
++                      Logger::warning("failed to open envsys dict");
++                      return {0, 0.0, 0, ""};
++              }
++
++              if (prop_dictionary_count(dict) == 0) {
++                      if (fd != -1) {
++                              close(fd);
++                      }
++                      has_battery = false;
++                      Logger::warning("no drivers registered for envsys");
++                      return {0, 0.0, 0, ""};
++              }
++
++              prop_object_t fieldsArray = prop_dictionary_get(prop_dictionary_t(dict), "acpibat0");
++              if (prop_object_type(fieldsArray) != PROP_TYPE_ARRAY) {
++                      if (fd != -1) {
++                              close(fd);
 +                      }
++                      has_battery = false;
++                      Logger::warning("unknown device 'acpibat0'");
++                      return {0, 0.0, 0, ""};
 +              }
 +
-+              return {percent, 0.0, seconds, status};
++              prop_object_iterator_t fieldsIter = prop_array_iterator(prop_array_t(fieldsArray));
++              if (fieldsIter == NULL) {
++                      if (fd != -1) {
++                              close(fd);
++                      }
++                      has_battery = false;
++                      return {0, 0.0, 0, ""};
++              }
++
++              /* only assume battery is not present if explicitly stated */
++              bool isBattery = false;
++              int64_t isPresent = 1;
++              int64_t curCharge = 0;
++              int64_t maxCharge = 0;
++              string status = "unknown";
++              string prop_description = "no description";
++
++              while ((fields = (prop_dictionary_t) prop_object_iterator_next(prop_object_iterator_t(fieldsIter))) != NULL) {
++                      props = (prop_dictionary_t) prop_dictionary_get(fields, "device-properties");
++                      if (props != NULL) continue;
++
++                      prop_object_t curValue = prop_dictionary_get(fields, "cur-value");
++                      prop_object_t maxValue = prop_dictionary_get(fields, "max-value");
++                      prop_object_t description = prop_dictionary_get(fields, "description");
++
++                      if (description == NULL || curValue == NULL) {
++                              continue;
++                      }
++
++
++                      prop_description = prop_string_cstring(prop_string_t(description));
++
++                      if (prop_description == "charge") {
++                              if (maxValue == NULL) {
++                                      continue;
++                              }
++                              curCharge = prop_number_integer_value(prop_number_t(curValue));
++                              maxCharge = prop_number_integer_value(prop_number_t(maxValue));
++                      }
++
++                      if (prop_description == "present") {
++                              isPresent = prop_number_integer_value(prop_number_t(curValue));
++                      }
++
++                      if (prop_description == "charging") {
++                              status = prop_description;
++                              string charging_type = prop_string_cstring(prop_string_t(prop_dictionary_get(fields, "type")));
++                              isBattery = charging_type == "Battery charge" ? true : false;
++                      }
++
++                      if (isBattery && isPresent) {
++                              totalCharge += curCharge;
++                              totalCapacity += maxCharge;
++                      }
++              }
++
++              prop_object_iterator_release(fieldsIter);
++              prop_object_release(dict);
++
++              uint32_t percent = ((double)totalCharge / (double)totalCapacity) * 100.0;
++
++              if (percent == 100) {
++                      status = "full";
++              }
++
++              return {percent, -1, -1, status};
 +      }
 +
 +      auto collect(bool no_update) -> cpu_info & {
@@ -569,7 +613,7 @@ Add support for NetBSD.
 +
 +              size_t size;
 +              if (sysctl(mib, 3, NULL, &size, NULL, 0) == -1) {
-+                      Logger::error("sysctl hw.drivestats failed");
++                      Logger::error("sysctl hw.drivestats failed");
 +                      return;
 +              }
 +              num_drives = size / sizeof(struct io_sysctl);
@@ -580,12 +624,12 @@ Add support for NetBSD.
 +              };
 +
 +              if (sysctl(mib, 3, drives.get(), &size, NULL, 0) == -1) {
-+                      Logger::error("sysctl hw.iostats failed");
++                      Logger::error("sysctl hw.iostats failed");
 +              }
 +              for (int i = 0; i < num_drives; i++) {
 +                      for (auto& [ignored, disk] : disks) {
 +                              if (disk.dev.string().find(drives[i].name) != string::npos) {
-+                                      string mountpoint = mapping.at(disk.dev);
++                                      string mountpoint = mapping.at(disk.dev);
 +                                      total_bytes_read = drives[i].rbytes;
 +                                      total_bytes_write = drives[i].wbytes;
 +                                      assign_values(disk, total_bytes_read, total_bytes_write);
@@ -778,7 +822,7 @@ Add support for NetBSD.
 +      class getifaddr_wrapper {
 +              struct ifaddrs *ifaddr;
 +
-+         public:
++      public:
 +              int status;
 +              getifaddr_wrapper() { status = getifaddrs(&ifaddr); }
 +              ~getifaddr_wrapper() { freeifaddrs(ifaddr); }