summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJakob P. Liljenberg <admin@qvantnet.com>2024-02-11 17:49:35 +0100
committerGitHub <noreply@github.com>2024-02-11 17:49:35 +0100
commit283ad3e76e085aa88b96ad6b5b30df255ea31c49 (patch)
tree4e4e6fd452889aeb1ce92b10f538709b387b50a0 /src
parentf2ead3d3a9dbc78ada36a0b79068c6aa5c7023fd (diff)
parent97e78ebb12ad77899c7e0f5999bf49c6230a31c6 (diff)
Merge branch 'main' into utf8-ctype
Diffstat (limited to 'src')
-rw-r--r--src/btop.cpp77
-rw-r--r--src/btop_config.cpp8
-rw-r--r--src/btop_draw.cpp17
-rw-r--r--src/btop_input.cpp7
-rw-r--r--src/btop_menu.cpp6
-rw-r--r--src/btop_shared.hpp4
-rw-r--r--src/btop_tools.hpp8
-rw-r--r--src/freebsd/btop_collect.cpp13
-rw-r--r--src/linux/btop_collect.cpp92
-rw-r--r--src/openbsd/btop_collect.cpp8
-rw-r--r--src/osx/btop_collect.cpp20
11 files changed, 185 insertions, 75 deletions
diff --git a/src/btop.cpp b/src/btop.cpp
index 864ecea..5b22d79 100644
--- a/src/btop.cpp
+++ b/src/btop.cpp
@@ -53,6 +53,7 @@ tab-size = 4
#include "btop_draw.hpp"
#include "btop_menu.hpp"
#include "fmt/core.h"
+#include "fmt/ostream.h"
using std::atomic;
using std::cout;
@@ -108,6 +109,7 @@ namespace Global {
atomic<bool> should_sleep (false);
atomic<bool> _runner_started (false);
atomic<bool> init_conf (false);
+ atomic<bool> reload_conf (false);
bool arg_tty{};
bool arg_low_color{};
@@ -364,7 +366,36 @@ void _signal_handler(const int sig) {
case SIGUSR1:
// Input::poll interrupt
break;
+ case SIGUSR2:
+ Global::reload_conf = true;
+ Input::interrupt();
+ break;
+ }
+}
+
+//* Config init
+void init_config(){
+ atomic_lock lck(Global::init_conf);
+ vector<string> load_warnings;
+ Config::load(Config::conf_file, load_warnings);
+ Config::set("lowcolor", (Global::arg_low_color ? true : not Config::getB("truecolor")));
+
+ static bool first_init = true;
+
+ if (Global::debug and first_init) {
+ Logger::set("DEBUG");
+ Logger::debug("Running in DEBUG mode!");
+ }
+ else Logger::set(Config::getS("log_level"));
+
+ static string log_level;
+ if (const string current_level = Config::getS("log_level"); log_level != current_level) {
+ log_level = current_level;
+ Logger::info("Logger set to " + (Global::debug ? "DEBUG" : log_level));
}
+
+ for (const auto& err_str : load_warnings) Logger::warning(err_str);
+ first_init = false;
}
//* Manages secondary thread for collection and drawing of boxes
@@ -895,22 +926,7 @@ int main(int argc, char **argv) {
}
//? Config init
- {
- atomic_lock lck(Global::init_conf);
- vector<string> load_warnings;
- Config::load(Config::conf_file, load_warnings);
- Config::set("lowcolor", (Global::arg_low_color ? true : not Config::getB("truecolor")));
-
- if (Global::debug) {
- Logger::set("DEBUG");
- Logger::debug("Starting in DEBUG mode!");
- }
- else Logger::set(Config::getS("log_level"));
-
- Logger::info("Logger set to " + (Global::debug ? "DEBUG" : Config::getS("log_level")));
-
- for (const auto& err_str : load_warnings) Logger::warning(err_str);
- }
+ init_config();
//? Try to find and set a UTF-8 locale
if (std::setlocale(LC_ALL, "") != nullptr and not s_contains((string)std::setlocale(LC_ALL, ""), ";")
@@ -1035,6 +1051,7 @@ int main(int argc, char **argv) {
std::signal(SIGCONT, _signal_handler);
std::signal(SIGWINCH, _signal_handler);
std::signal(SIGUSR1, _signal_handler);
+ std::signal(SIGUSR2, _signal_handler);
sigset_t mask;
sigemptyset(&mask);
@@ -1086,9 +1103,27 @@ int main(int argc, char **argv) {
try {
while (not true not_eq not false) {
//? Check for exceptions in secondary thread and exit with fail signal if true
- if (Global::thread_exception) clean_quit(1);
- else if (Global::should_quit) clean_quit(0);
- else if (Global::should_sleep) { Global::should_sleep = false; _sleep(); }
+ if (Global::thread_exception) {
+ clean_quit(1);
+ }
+ else if (Global::should_quit) {
+ clean_quit(0);
+ }
+ else if (Global::should_sleep) {
+ Global::should_sleep = false;
+ _sleep();
+ }
+ //? Hot reload config from CTRL + R or SIGUSR2
+ else if (Global::reload_conf) {
+ Global::reload_conf = false;
+ if (Runner::active) Runner::stop();
+ Config::unlock();
+ init_config();
+ Theme::updateThemes();
+ Theme::setTheme();
+ Draw::banner_gen(0, 0, false, true);
+ Global::resized = true;
+ }
//? Make sure terminal size hasn't changed (in case of SIGWINCH not working properly)
term_resize(Global::resized);
@@ -1123,9 +1158,9 @@ int main(int argc, char **argv) {
update_ms = Config::getI("update_ms");
future_time = time_ms() + update_ms;
}
- else if (future_time - current_time > update_ms)
+ else if (future_time - current_time > update_ms) {
future_time = current_time;
-
+ }
//? Poll for input and process any input detected
else if (Input::poll(min((uint64_t)1000, future_time - current_time))) {
if (not Runner::active) Config::unlock();
diff --git a/src/btop_config.cpp b/src/btop_config.cpp
index 18e60ae..aa4d813 100644
--- a/src/btop_config.cpp
+++ b/src/btop_config.cpp
@@ -199,6 +199,8 @@ namespace Config {
{"selected_battery", "#* Which battery to use if multiple are present. \"Auto\" for auto detection."},
+ {"show_battery_watts", "#* Show power stats of battery next to charge indicator."},
+
{"log_level", "#* Set loglevel for \"~/.config/btop/btop.log\" levels are: \"ERROR\" \"WARNING\" \"INFO\" \"DEBUG\".\n"
"#* The level set includes all lower levels, i.e. \"DEBUG\" will show all logging info."},
#ifdef GPU_SUPPORT
@@ -293,6 +295,7 @@ namespace Config {
{"net_auto", true},
{"net_sync", true},
{"show_battery", true},
+ {"show_battery_watts", true},
{"vim_keys", false},
{"tty_mode", false},
{"disk_free_priv", false},
@@ -729,9 +732,9 @@ namespace Config {
if (geteuid() != Global::real_uid and seteuid(Global::real_uid) != 0) return;
std::ofstream cwrite(conf_file, std::ios::trunc);
if (cwrite.good()) {
- cwrite << "#? Config file for btop v. " << Global::Version;
+ cwrite << "#? Config file for btop v. " << Global::Version << "\n";
for (auto [name, description] : descriptions) {
- cwrite << "\n\n" << (description.empty() ? "" : description + "\n")
+ cwrite << "\n" << (description.empty() ? "" : description + "\n")
<< name << " = ";
if (strings.contains(name))
cwrite << "\"" << strings.at(name) << "\"";
@@ -739,6 +742,7 @@ namespace Config {
cwrite << ints.at(name);
else if (bools.contains(name))
cwrite << (bools.at(name) ? "True" : "False");
+ cwrite << "\n";
}
}
}
diff --git a/src/btop_draw.cpp b/src/btop_draw.cpp
index acab14c..bfd12ce 100644
--- a/src/btop_draw.cpp
+++ b/src/btop_draw.cpp
@@ -706,6 +706,7 @@ namespace Cpu {
if (Config::getB("show_battery") and has_battery) {
static int old_percent{}; // defaults to = 0
static long old_seconds{}; // defaults to = 0
+ static float old_watts{}; // defaults to = 0
static string old_status;
static Draw::Meter bat_meter {10, "cpu", true};
static const std::unordered_map<string, string> bat_symbols = {
@@ -715,16 +716,18 @@ namespace Cpu {
{"unknown", "○"}
};
- const auto& [percent, seconds, status] = current_bat;
+ const auto& [percent, watts, seconds, status] = current_bat;
- if (redraw or percent != old_percent or seconds != old_seconds or status != old_status) {
+ if (redraw or percent != old_percent or (watts != old_watts and Config::getB("show_battery_watts")) or seconds != old_seconds or status != old_status) {
old_percent = percent;
+ old_watts = watts;
old_seconds = seconds;
old_status = status;
const string str_time = (seconds > 0 ? sec_to_dhms(seconds, true, true) : "");
const string str_percent = to_string(percent) + '%';
+ const string str_watts = (watts != -1 and Config::getB("show_battery_watts") ? fmt::format("{:.2f}", watts) + 'W' : "");
const auto& bat_symbol = bat_symbols.at((bat_symbols.contains(status) ? status : "unknown"));
- const int current_len = (Term::width >= 100 ? 11 : 0) + str_time.size() + str_percent.size() + to_string(Config::getI("update_ms")).size();
+ const int current_len = (Term::width >= 100 ? 11 : 0) + str_time.size() + str_percent.size() + str_watts.size() + to_string(Config::getI("update_ms")).size();
const int current_pos = Term::width - current_len - 17;
if ((bat_pos != current_pos or bat_len != current_len) and bat_pos > 0 and not redraw)
@@ -734,7 +737,7 @@ namespace Cpu {
out += Mv::to(y, bat_pos) + title_left + Theme::c("title") + Fx::b + "BAT" + bat_symbol + ' ' + str_percent
+ (Term::width >= 100 ? Fx::ub + ' ' + bat_meter(percent) + Fx::b : "")
- + (not str_time.empty() ? ' ' + Theme::c("title") + str_time : " ") + Fx::ub + title_right;
+ + (not str_time.empty() ? ' ' + Theme::c("title") + str_time : "") + (not str_watts.empty() ? " " + Theme::c("title") + Fx::b + str_watts : "") + Fx::ub + title_right;
}
}
else if (bat_pos > 0) {
@@ -1361,6 +1364,7 @@ namespace Net {
int x = 1, y, width = 20, height;
int b_x, b_y, b_width, b_height, d_graph_height, u_graph_height;
bool shown = true, redraw = true;
+ const int MAX_IFNAMSIZ = 15;
string old_ip;
std::unordered_map<string, Draw::Graph> graphs;
string box;
@@ -1381,7 +1385,7 @@ namespace Net {
out.reserve(width * height);
const string title_left = Theme::c("net_box") + Fx::ub + Symbols::title_left;
const string title_right = Theme::c("net_box") + Fx::ub + Symbols::title_right;
- const int i_size = min((int)selected_iface.size(), 10);
+ const int i_size = min((int)selected_iface.size(), MAX_IFNAMSIZ);
const long long down_max = (net_auto ? safeVal(graph_max, "download"s) : ((long long)(Config::getI("net_download")) << 20) / 8);
const long long up_max = (net_auto ? safeVal(graph_max, "upload"s) : ((long long)(Config::getI("net_upload")) << 20) / 8);
@@ -1403,7 +1407,7 @@ namespace Net {
//? Interface selector and buttons
out += Mv::to(y, x+width - i_size - 9) + title_left + Fx::b + Theme::c("hi_fg") + "<b " + Theme::c("title")
- + uresize(selected_iface, 10) + Theme::c("hi_fg") + " n>" + title_right
+ + uresize(selected_iface, MAX_IFNAMSIZ) + Theme::c("hi_fg") + " n>" + title_right
+ Mv::to(y, x+width - i_size - 15) + title_left + Theme::c("hi_fg") + (safeVal(net.stat, "download"s).offset + safeVal(net.stat, "upload"s).offset > 0 ? Fx::b : "") + 'z'
+ Theme::c("title") + "ero" + title_right;
Input::mouse_mappings["b"] = {y, x+width - i_size - 8, 1, 3};
@@ -2238,3 +2242,4 @@ namespace Draw {
}
}
}
+
diff --git a/src/btop_input.cpp b/src/btop_input.cpp
index fbbae58..6bfe9d8 100644
--- a/src/btop_input.cpp
+++ b/src/btop_input.cpp
@@ -41,6 +41,7 @@ namespace Input {
//* Map for translating key codes to readable values
const std::unordered_map<string, string> Key_escapes = {
{"\033", "escape"},
+ {"\x12", "ctrl_r"},
{"\n", "enter"},
{" ", "space"},
{"\x7f", "backspace"},
@@ -258,8 +259,10 @@ namespace Input {
Draw::calcSizes();
Runner::run("all", false, true);
return;
- }
- else
+ } else if (is_in(key, "ctrl_r")) {
+ kill(getpid(), SIGUSR2);
+ return;
+ } else
keep_going = true;
if (not keep_going) return;
diff --git a/src/btop_menu.cpp b/src/btop_menu.cpp
index fb119aa..fbf07c2 100644
--- a/src/btop_menu.cpp
+++ b/src/btop_menu.cpp
@@ -177,6 +177,7 @@ namespace Menu {
{"F2, o", "Shows options."},
{"F1, ?, h", "Shows this window."},
{"ctrl + z", "Sleep program and put in background."},
+ {"ctrl + r", "Reloads config file from disk."},
{"q, ctrl + c", "Quits program."},
{"+, -", "Add/Subtract 100ms to/from update timer."},
{"Up, Down", "Select in process list."},
@@ -353,6 +354,11 @@ namespace Menu {
"Can be both batteries and UPS.",
"",
"\"Auto\" for auto detection."},
+ {"show_battery_watts",
+ "Show battery power.",
+ "",
+ "Show discharge power when discharging.",
+ "Show charging power when charging."},
{"log_level",
"Set loglevel for error.log",
"",
diff --git a/src/btop_shared.hpp b/src/btop_shared.hpp
index 69566c6..c543d9e 100644
--- a/src/btop_shared.hpp
+++ b/src/btop_shared.hpp
@@ -178,7 +178,7 @@ namespace Cpu {
extern string cpuName, cpuHz;
extern vector<string> available_fields;
extern vector<string> available_sensors;
- extern tuple<int, long, string> current_bat;
+ extern tuple<int, float, long, string> current_bat;
struct cpu_info {
std::unordered_map<string, deque<long long>> cpu_percent = {
@@ -213,7 +213,7 @@ namespace Cpu {
auto get_cpuHz() -> string;
//* Get battery info from /sys
- auto get_battery() -> tuple<int, long, string>;
+ auto get_battery() -> tuple<int, float, long, string>;
}
namespace Mem {
diff --git a/src/btop_tools.hpp b/src/btop_tools.hpp
index 705a5eb..2502786 100644
--- a/src/btop_tools.hpp
+++ b/src/btop_tools.hpp
@@ -18,6 +18,10 @@ tab-size = 4
#pragma once
+#if !defined(NDEBUG)
+# define BTOP_DEBUG
+#endif
+
#include <algorithm> // for std::ranges::count_if
#include <array>
#include <atomic>
@@ -42,11 +46,9 @@ tab-size = 4
#define HOST_NAME_MAX 64
#endif
#endif
-#define FMT_HEADER_ONLY
+
#include "fmt/core.h"
#include "fmt/format.h"
-#include "fmt/ostream.h"
-#include "fmt/ranges.h"
using std::array;
using std::atomic;
diff --git a/src/freebsd/btop_collect.cpp b/src/freebsd/btop_collect.cpp
index 2db49a2..38f4368 100644
--- a/src/freebsd/btop_collect.cpp
+++ b/src/freebsd/btop_collect.cpp
@@ -207,7 +207,7 @@ namespace Cpu {
string cpuName;
string cpuHz;
bool has_battery = true;
- tuple<int, long, string> current_bat;
+ tuple<int, float, long, string> current_bat;
const array<string, 10> time_names = {"user", "nice", "system", "idle"};
@@ -373,10 +373,11 @@ namespace Cpu {
return core_map;
}
- auto get_battery() -> tuple<int, long, string> {
- if (not has_battery) return {0, 0, ""};
+ auto get_battery() -> tuple<int, float, long, string> {
+ if (not has_battery) return {0, 0, 0, ""};
long seconds = -1;
+ float watts = -1;
uint32_t percent = -1;
size_t size = sizeof(percent);
string status = "discharging";
@@ -388,6 +389,10 @@ namespace Cpu {
if (sysctlbyname("hw.acpi.battery.time", &seconds, &size, nullptr, 0) < 0) {
seconds = 0;
}
+ size = sizeof(watts);
+ if (sysctlbyname("hw.acpi.battery.rate", &watts, &size, nullptr, 0) < 0) {
+ watts = -1;
+ }
int state;
size = sizeof(state);
if (sysctlbyname("hw.acpi.battery.state", &state, &size, nullptr, 0) < 0) {
@@ -402,7 +407,7 @@ namespace Cpu {
}
}
- return {percent, seconds, status};
+ return {percent, watts, seconds, status};
}
auto collect(bool no_update) -> cpu_info & {
diff --git a/src/linux/btop_collect.cpp b/src/linux/btop_collect.cpp
index eb8c2b7..739d587 100644
--- a/src/linux/btop_collect.cpp
+++ b/src/linux/btop_collect.cpp
@@ -301,7 +301,7 @@ namespace Cpu {
string cpuName;
string cpuHz;
bool has_battery = true;
- tuple<int, long, string> current_bat;
+ tuple<int, float, long, string> current_bat;
const array time_names {
"user"s, "nice"s, "system"s, "idle"s, "iowait"s,
@@ -590,7 +590,7 @@ namespace Cpu {
cpuhz += " GHz";
}
else if (hz > 0)
- cpuhz = to_string((int)round(hz)) + " MHz";
+ cpuhz = to_string((int)hz) + " MHz";
}
catch (const std::exception& e) {
@@ -671,13 +671,14 @@ namespace Cpu {
}
struct battery {
- fs::path base_dir, energy_now, energy_full, power_now, status, online;
+ fs::path base_dir, energy_now, charge_now, energy_full, charge_full, power_now, current_now, voltage_now, status, online;
string device_type;
- bool use_energy = true;
+ bool use_energy_or_charge = true;
+ bool use_power = true;
};
- auto get_battery() -> tuple<int, long, string> {
- if (not has_battery) return {0, 0, ""};
+ auto get_battery() -> tuple<int, float, long, string> {
+ if (not has_battery) return {0, 0, 0, ""};
static string auto_sel;
static std::unordered_map<string, battery> batteries;
@@ -709,19 +710,27 @@ namespace Cpu {
}
if (fs::exists(bat_dir / "energy_now")) new_bat.energy_now = bat_dir / "energy_now";
- else if (fs::exists(bat_dir / "charge_now")) new_bat.energy_now = bat_dir / "charge_now";
- else new_bat.use_energy = false;
+ else if (fs::exists(bat_dir / "charge_now")) new_bat.charge_now = bat_dir / "charge_now";
+ else new_bat.use_energy_or_charge = false;
if (fs::exists(bat_dir / "energy_full")) new_bat.energy_full = bat_dir / "energy_full";
- else if (fs::exists(bat_dir / "charge_full")) new_bat.energy_full = bat_dir / "charge_full";
- else new_bat.use_energy = false;
+ else if (fs::exists(bat_dir / "charge_full")) new_bat.charge_full = bat_dir / "charge_full";
+ else new_bat.use_energy_or_charge = false;
- if (not new_bat.use_energy and not fs::exists(bat_dir / "capacity")) {
+ if (not new_bat.use_energy_or_charge and not fs::exists(bat_dir / "capacity")) {
continue;
}
- if (fs::exists(bat_dir / "power_now")) new_bat.power_now = bat_dir / "power_now";
- else if (fs::exists(bat_dir / "current_now")) new_bat.power_now = bat_dir / "current_now";
+ if (fs::exists(bat_dir / "power_now")) {
+ new_bat.power_now = bat_dir / "power_now";
+ }
+ else if ((fs::exists(bat_dir / "current_now")) and (fs::exists(bat_dir / "current_now"))) {
+ new_bat.current_now = bat_dir / "current_now";
+ new_bat.voltage_now = bat_dir / "voltage_now";
+ }
+ else {
+ new_bat.use_power = false;
+ }
if (fs::exists(bat_dir / "AC0/online")) new_bat.online = bat_dir / "AC0/online";
else if (fs::exists(bat_dir / "AC/online")) new_bat.online = bat_dir / "AC/online";
@@ -736,7 +745,7 @@ namespace Cpu {
}
if (batteries.empty()) {
has_battery = false;
- return {0, 0, ""};
+ return {0, 0, 0, ""};
}
}
@@ -756,25 +765,33 @@ namespace Cpu {
int percent = -1;
long seconds = -1;
+ float watts = -1;
//? Try to get battery percentage
- if (b.use_energy) {
+ if (percent < 0) {
+ try {
+ percent = stoll(readfile(b.base_dir / "capacity", "-1"));
+ }
+ catch (const std::invalid_argument&) { }
+ catch (const std::out_of_range&) { }
+ }
+ if (b.use_energy_or_charge and percent < 0) {
try {
percent = round(100.0 * stoll(readfile(b.energy_now, "-1")) / stoll(readfile(b.energy_full, "1")));
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
}
- if (percent < 0) {
+ if (b.use_energy_or_charge and percent < 0) {
try {
- percent = stoll(readfile(b.base_dir / "capacity", "-1"));
+ percent = round(100.0 * stoll(readfile(b.charge_now, "-1")) / stoll(readfile(b.charge_full, "1")));
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
}
if (percent < 0) {
has_battery = false;
- return {0, 0, ""};
+ return {0, 0, 0, ""};
}
//? Get charging/discharging status
@@ -788,23 +805,52 @@ namespace Cpu {
//? Get seconds to empty
if (not is_in(status, "charging", "full")) {
- if (b.use_energy and not b.power_now.empty()) {
+ if (b.use_energy_or_charge ) {
+ if (not b.power_now.empty()) {
+ try {
+ seconds = round((double)stoll(readfile(b.energy_now, "0")) / stoll(readfile(b.power_now, "1")) * 3600);
+ }
+ catch (const std::invalid_argument&) { }
+ catch (const std::out_of_range&) { }
+ }
+ else if (not b.current_now.empty()) {
+ try {
+ seconds = round((double)stoll(readfile(b.charge_now, "0")) / (double)stoll(readfile(b.current_now, "1")) * 3600);
+ }
+ catch (const std::invalid_argument&) { }
+ catch (const std::out_of_range&) { }
+ }
+ }
+
+ if (seconds < 0 and fs::exists(b.base_dir / "time_to_empty")) {
try {
- seconds = round((double)stoll(readfile(b.energy_now, "0")) / stoll(readfile(b.power_now, "1")) * 3600);
+ seconds = stoll(readfile(b.base_dir / "time_to_empty", "0")) * 60;
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
}
- if (seconds < 0 and fs::exists(b.base_dir / "time_to_empty")) {
+ }
+
+ //? Get power draw
+ if (b.use_power) {
+ if (not b.power_now.empty()) {
try {
- seconds = stoll(readfile(b.base_dir / "time_to_empty", "0")) * 60;
+ watts = (float)stoll(readfile(b.energy_now, "-1")) / 1000000.0;
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
}
+ else if (not b.voltage_now.empty() and not b.current_now.empty()) {
+ try {
+ watts = (float)stoll(readfile(b.current_now, "-1")) / 1000000.0 * stoll(readfile(b.voltage_now, "1")) / 1000000.0;
+ }
+ catch (const std::invalid_argument&) { }
+ catch (const std::out_of_range&) { }
+ }
+
}
- return {percent, seconds, status};
+ return {percent, watts, seconds, status};
}
auto collect(bool no_update) -> cpu_info& {
diff --git a/src/openbsd/btop_collect.cpp b/src/openbsd/btop_collect.cpp
index df35662..3784ea9 100644
--- a/src/openbsd/btop_collect.cpp
+++ b/src/openbsd/btop_collect.cpp
@@ -202,7 +202,7 @@ namespace Cpu {
string cpuName;
string cpuHz;
bool has_battery = true;
- tuple<int, long, string> current_bat;
+ tuple<int, float, long, string> current_bat;
const array<string, 10> time_names = {"user", "nice", "system", "idle"};
@@ -385,8 +385,8 @@ namespace Cpu {
return core_map;
}
- auto get_battery() -> tuple<int, long, string> {
- if (not has_battery) return {0, 0, ""};
+ auto get_battery() -> tuple<int, float, long, string> {
+ if (not has_battery) return {0, 0, 0, ""};
long seconds = -1;
uint32_t percent = -1;
@@ -417,7 +417,7 @@ namespace Cpu {
}
}
- return {percent, seconds, status};
+ return {percent, -1, seconds, status};
}
auto collect(bool no_update) -> cpu_info & {
diff --git a/src/osx/btop_collect.cpp b/src/osx/btop_collect.cpp
index 860e457..df1fca3 100644
--- a/src/osx/btop_collect.cpp
+++ b/src/osx/btop_collect.cpp
@@ -191,7 +191,7 @@ namespace Cpu {
string cpuHz;
bool has_battery = true;
bool macM1 = false;
- tuple<int, long, string> current_bat;
+ tuple<int, float, long, string> current_bat;
const array<string, 10> time_names = {"user", "nice", "system", "idle"};
@@ -407,8 +407,8 @@ namespace Cpu {
~IOPSList_Wrap() { CFRelease(data); }
};
- auto get_battery() -> tuple<int, long, string> {
- if (not has_battery) return {0, 0, ""};
+ auto get_battery() -> tuple<int, float, long, string> {
+ if (not has_battery) return {0, 0, 0, ""};
uint32_t percent = -1;
long seconds = -1;
@@ -447,7 +447,7 @@ namespace Cpu {
has_battery = false;
}
}
- return {percent, seconds, status};
+ return {percent, -1, seconds, status};
}
auto collect(bool no_update) -> cpu_info & {
@@ -1212,10 +1212,14 @@ namespace Proc {
//? Get program name, command, username, parent pid, nice and status
if (no_cache) {
char fullname[PROC_PIDPATHINFO_MAXSIZE];
- proc_pidpath(pid, fullname, sizeof(fullname));
- const string f_name = std::string(fullname);
- size_t lastSlash = f_name.find_last_of('/');
- new_proc.name = f_name.substr(lastSlash + 1);
+ int rc = proc_pidpath(pid, fullname, sizeof(fullname));
+ string f_name = "<defunct>";
+ if (rc != 0) {
+ f_name = std::string(fullname);
+ size_t lastSlash = f_name.find_last_of('/');
+ f_name = f_name.substr(lastSlash + 1);
+ }
+ new_proc.name = f_name;
//? Get process arguments if possible, fallback to process path in case of failure
if (Shared::arg_max > 0) {
std::unique_ptr<char[]> proc_chars(new char[Shared::arg_max]);