mirror of
https://github.com/aristocratos/btop.git
synced 2024-09-27 22:01:29 +02:00
reformat
This commit is contained in:
parent
1fd625086b
commit
264bf2d7da
@ -16,25 +16,25 @@ indent = tab
|
|||||||
tab-size = 4
|
tab-size = 4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <ranges>
|
|
||||||
#include <cmath>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <numeric>
|
|
||||||
#include <regex>
|
|
||||||
#include <sys/statvfs.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <string>
|
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#include <net/if.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#include <libproc.h>
|
#include <libproc.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <btop_shared.hpp>
|
|
||||||
#include <btop_config.hpp>
|
#include <btop_config.hpp>
|
||||||
|
#include <btop_shared.hpp>
|
||||||
#include <btop_tools.hpp>
|
#include <btop_tools.hpp>
|
||||||
|
#include <cmath>
|
||||||
|
#include <fstream>
|
||||||
|
#include <numeric>
|
||||||
|
#include <ranges>
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
using std::clamp, std::string_literals::operator""s, std::cmp_equal, std::cmp_less, std::cmp_greater;
|
using std::clamp, std::string_literals::operator""s, std::cmp_equal, std::cmp_less, std::cmp_greater;
|
||||||
using std::ifstream, std::numeric_limits, std::streamsize, std::round, std::max, std::min;
|
using std::ifstream, std::numeric_limits, std::streamsize, std::round, std::max, std::min;
|
||||||
@ -44,8 +44,7 @@ using namespace Tools;
|
|||||||
|
|
||||||
//? --------------------------------------------------- FUNCTIONS -----------------------------------------------------
|
//? --------------------------------------------------- FUNCTIONS -----------------------------------------------------
|
||||||
|
|
||||||
namespace Cpu
|
namespace Cpu {
|
||||||
{
|
|
||||||
vector<long long> core_old_totals;
|
vector<long long> core_old_totals;
|
||||||
vector<long long> core_old_idles;
|
vector<long long> core_old_idles;
|
||||||
vector<string> available_fields;
|
vector<string> available_fields;
|
||||||
@ -63,8 +62,7 @@ namespace Cpu
|
|||||||
//* Search /proc/cpuinfo for a cpu name
|
//* Search /proc/cpuinfo for a cpu name
|
||||||
string get_cpuName();
|
string get_cpuName();
|
||||||
|
|
||||||
struct Sensor
|
struct Sensor {
|
||||||
{
|
|
||||||
fs::path path;
|
fs::path path;
|
||||||
string label;
|
string label;
|
||||||
int64_t temp = 0;
|
int64_t temp = 0;
|
||||||
@ -76,24 +74,20 @@ namespace Cpu
|
|||||||
string cpu_sensor;
|
string cpu_sensor;
|
||||||
vector<string> core_sensors;
|
vector<string> core_sensors;
|
||||||
unordered_flat_map<int, int> core_mapping;
|
unordered_flat_map<int, int> core_mapping;
|
||||||
}
|
} // namespace Cpu
|
||||||
|
|
||||||
namespace Mem
|
namespace Mem {
|
||||||
{
|
|
||||||
double old_uptime;
|
double old_uptime;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Shared
|
namespace Shared {
|
||||||
{
|
|
||||||
|
|
||||||
fs::path passwd_path;
|
fs::path passwd_path;
|
||||||
uint64_t totalMem;
|
uint64_t totalMem;
|
||||||
long pageSize, clkTck, coreCount;
|
long pageSize, clkTck, coreCount;
|
||||||
int totalMem_len;
|
int totalMem_len;
|
||||||
|
|
||||||
void init()
|
void init() {
|
||||||
{
|
|
||||||
|
|
||||||
//? Shared global variables init
|
//? Shared global variables init
|
||||||
|
|
||||||
// passwd_path = (fs::is_regular_file(fs::path("/etc/passwd")) and access("/etc/passwd", R_OK) != -1) ? "/etc/passwd" : "";
|
// passwd_path = (fs::is_regular_file(fs::path("/etc/passwd")) and access("/etc/passwd", R_OK) != -1) ? "/etc/passwd" : "";
|
||||||
@ -101,30 +95,26 @@ namespace Shared
|
|||||||
// Logger::warning("Could not read /etc/passwd, will show UID instead of username.");
|
// Logger::warning("Could not read /etc/passwd, will show UID instead of username.");
|
||||||
|
|
||||||
coreCount = sysconf(_SC_NPROCESSORS_ONLN);
|
coreCount = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
if (coreCount < 1)
|
if (coreCount < 1) {
|
||||||
{
|
|
||||||
coreCount = 1;
|
coreCount = 1;
|
||||||
Logger::warning("Could not determine number of cores, defaulting to 1.");
|
Logger::warning("Could not determine number of cores, defaulting to 1.");
|
||||||
}
|
}
|
||||||
|
|
||||||
pageSize = sysconf(_SC_PAGE_SIZE);
|
pageSize = sysconf(_SC_PAGE_SIZE);
|
||||||
if (pageSize <= 0)
|
if (pageSize <= 0) {
|
||||||
{
|
|
||||||
pageSize = 4096;
|
pageSize = 4096;
|
||||||
Logger::warning("Could not get system page size. Defaulting to 4096, processes memory usage might be incorrect.");
|
Logger::warning("Could not get system page size. Defaulting to 4096, processes memory usage might be incorrect.");
|
||||||
}
|
}
|
||||||
|
|
||||||
clkTck = sysconf(_SC_CLK_TCK);
|
clkTck = sysconf(_SC_CLK_TCK);
|
||||||
if (clkTck <= 0)
|
if (clkTck <= 0) {
|
||||||
{
|
|
||||||
clkTck = 100;
|
clkTck = 100;
|
||||||
Logger::warning("Could not get system clock ticks per second. Defaulting to 100, processes cpu usage might be incorrect.");
|
Logger::warning("Could not get system clock ticks per second. Defaulting to 100, processes cpu usage might be incorrect.");
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t memsize = 0;
|
int64_t memsize = 0;
|
||||||
size_t size = sizeof(memsize);
|
size_t size = sizeof(memsize);
|
||||||
if (sysctlbyname("hw.memsize", &memsize, &size, NULL, 0) < 0)
|
if (sysctlbyname("hw.memsize", &memsize, &size, NULL, 0) < 0) {
|
||||||
{
|
|
||||||
Logger::warning("Could not get memory size");
|
Logger::warning("Could not get memory size");
|
||||||
}
|
}
|
||||||
totalMem = memsize;
|
totalMem = memsize;
|
||||||
@ -132,10 +122,9 @@ namespace Shared
|
|||||||
Cpu::cpuName = Cpu::get_cpuName();
|
Cpu::cpuName = Cpu::get_cpuName();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace Shared
|
||||||
|
|
||||||
namespace Cpu
|
namespace Cpu {
|
||||||
{
|
|
||||||
string cpuName;
|
string cpuName;
|
||||||
string cpuHz;
|
string cpuHz;
|
||||||
bool has_battery = true;
|
bool has_battery = true;
|
||||||
@ -144,38 +133,34 @@ namespace Cpu
|
|||||||
const array<string, 10> time_names = {"user", "nice", "system", "idle", "iowait", "irq", "softirq", "steal", "guest", "guest_nice"};
|
const array<string, 10> time_names = {"user", "nice", "system", "idle", "iowait", "irq", "softirq", "steal", "guest", "guest_nice"};
|
||||||
|
|
||||||
unordered_flat_map<string, long long> cpu_old = {
|
unordered_flat_map<string, long long> cpu_old = {
|
||||||
{"totals", 0},
|
{"totals", 0},
|
||||||
{"idles", 0},
|
{"idles", 0},
|
||||||
{"user", 0},
|
{"user", 0},
|
||||||
{"nice", 0},
|
{"nice", 0},
|
||||||
{"system", 0},
|
{"system", 0},
|
||||||
{"idle", 0},
|
{"idle", 0},
|
||||||
{"iowait", 0},
|
{"iowait", 0},
|
||||||
{"irq", 0},
|
{"irq", 0},
|
||||||
{"softirq", 0},
|
{"softirq", 0},
|
||||||
{"steal", 0},
|
{"steal", 0},
|
||||||
{"guest", 0},
|
{"guest", 0},
|
||||||
{"guest_nice", 0}};
|
{"guest_nice", 0}};
|
||||||
|
|
||||||
string get_cpuName()
|
string get_cpuName() {
|
||||||
{
|
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
size_t size = sizeof(buffer);
|
size_t size = sizeof(buffer);
|
||||||
if (sysctlbyname("machdep.cpu.brand_string", &buffer, &size, NULL, 0) < 0)
|
if (sysctlbyname("machdep.cpu.brand_string", &buffer, &size, NULL, 0) < 0) {
|
||||||
{
|
|
||||||
Logger::error("Failed to get CPU name");
|
Logger::error("Failed to get CPU name");
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return string(buffer);
|
return string(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_sensors()
|
bool get_sensors() {
|
||||||
{
|
|
||||||
return not found_sensors.empty();
|
return not found_sensors.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_sensors()
|
void update_sensors() {
|
||||||
{
|
|
||||||
if (cpu_sensor.empty())
|
if (cpu_sensor.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -187,20 +172,16 @@ namespace Cpu
|
|||||||
if (current_cpu.temp.at(0).size() > 20)
|
if (current_cpu.temp.at(0).size() > 20)
|
||||||
current_cpu.temp.at(0).pop_front();
|
current_cpu.temp.at(0).pop_front();
|
||||||
|
|
||||||
if (Config::getB("show_coretemp") and not cpu_temp_only)
|
if (Config::getB("show_coretemp") and not cpu_temp_only) {
|
||||||
{
|
|
||||||
vector<string> done;
|
vector<string> done;
|
||||||
for (const auto &sensor : core_sensors)
|
for (const auto &sensor : core_sensors) {
|
||||||
{
|
|
||||||
if (v_contains(done, sensor))
|
if (v_contains(done, sensor))
|
||||||
continue;
|
continue;
|
||||||
found_sensors.at(sensor).temp = stol(readfile(found_sensors.at(sensor).path, "0")) / 1000;
|
found_sensors.at(sensor).temp = stol(readfile(found_sensors.at(sensor).path, "0")) / 1000;
|
||||||
done.push_back(sensor);
|
done.push_back(sensor);
|
||||||
}
|
}
|
||||||
for (const auto &[core, temp] : core_mapping)
|
for (const auto &[core, temp] : core_mapping) {
|
||||||
{
|
if (cmp_less(core + 1, current_cpu.temp.size()) and cmp_less(temp, core_sensors.size())) {
|
||||||
if (cmp_less(core + 1, current_cpu.temp.size()) and cmp_less(temp, core_sensors.size()))
|
|
||||||
{
|
|
||||||
current_cpu.temp.at(core + 1).push_back(found_sensors.at(core_sensors.at(temp)).temp);
|
current_cpu.temp.at(core + 1).push_back(found_sensors.at(core_sensors.at(temp)).temp);
|
||||||
if (current_cpu.temp.at(core + 1).size() > 20)
|
if (current_cpu.temp.at(core + 1).size() > 20)
|
||||||
current_cpu.temp.at(core + 1).pop_front();
|
current_cpu.temp.at(core + 1).pop_front();
|
||||||
@ -209,33 +190,29 @@ namespace Cpu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string get_cpuHz()
|
string get_cpuHz() {
|
||||||
{
|
|
||||||
uint64_t freq = 0;
|
uint64_t freq = 0;
|
||||||
size_t size = sizeof(freq);
|
size_t size = sizeof(freq);
|
||||||
|
|
||||||
return "1.0";
|
return "1.0";
|
||||||
if (sysctlbyname("hw.cpufrequency", &freq, &size, NULL, 0) < 0)
|
if (sysctlbyname("hw.cpufrequency", &freq, &size, NULL, 0) < 0) {
|
||||||
{
|
|
||||||
Logger::error("Failed to get CPU frequency");
|
Logger::error("Failed to get CPU frequency");
|
||||||
}
|
}
|
||||||
return "" + freq;
|
return "" + freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto get_core_mapping() -> unordered_flat_map<int, int>
|
auto get_core_mapping() -> unordered_flat_map<int, int> {
|
||||||
{
|
|
||||||
unordered_flat_map<int, int> core_map;
|
unordered_flat_map<int, int> core_map;
|
||||||
return core_map;
|
return core_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto get_battery() -> tuple<int, long, string>
|
auto get_battery() -> tuple<int, long, string> {
|
||||||
{
|
//if (not has_battery)
|
||||||
// if (not has_battery)
|
|
||||||
return {0, 0, ""};
|
return {0, 0, ""};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto collect(const bool no_update) -> cpu_info &
|
auto collect(const bool no_update) -> cpu_info & {
|
||||||
{
|
|
||||||
if (Runner::stopping or (no_update and not current_cpu.cpu_percent.at("total").empty()))
|
if (Runner::stopping or (no_update and not current_cpu.cpu_percent.at("total").empty()))
|
||||||
return current_cpu;
|
return current_cpu;
|
||||||
auto &cpu = current_cpu;
|
auto &cpu = current_cpu;
|
||||||
@ -245,10 +222,9 @@ namespace Cpu
|
|||||||
|
|
||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
}
|
} // namespace Cpu
|
||||||
|
|
||||||
namespace Mem
|
namespace Mem {
|
||||||
{
|
|
||||||
bool has_swap = false;
|
bool has_swap = false;
|
||||||
vector<string> fstab;
|
vector<string> fstab;
|
||||||
fs::file_time_type fstab_time;
|
fs::file_time_type fstab_time;
|
||||||
@ -257,55 +233,46 @@ namespace Mem
|
|||||||
|
|
||||||
mem_info current_mem{};
|
mem_info current_mem{};
|
||||||
|
|
||||||
auto collect(const bool no_update) -> mem_info &
|
auto collect(const bool no_update) -> mem_info & {
|
||||||
{
|
|
||||||
if (Runner::stopping or (no_update and not current_mem.percent.at("used").empty()))
|
if (Runner::stopping or (no_update and not current_mem.percent.at("used").empty()))
|
||||||
return current_mem;
|
return current_mem;
|
||||||
|
|
||||||
auto &show_disks = Config::getB("show_disks");
|
auto &show_disks = Config::getB("show_disks");
|
||||||
auto &mem = current_mem;
|
auto &mem = current_mem;
|
||||||
FILE *fpIn = popen("/usr/bin/vm_stat", "r");
|
FILE *fpIn = popen("/usr/bin/vm_stat", "r");
|
||||||
if (fpIn)
|
if (fpIn) {
|
||||||
{
|
|
||||||
char buf[512];
|
char buf[512];
|
||||||
while (fgets(buf, sizeof(buf), fpIn) != NULL)
|
while (fgets(buf, sizeof(buf), fpIn) != NULL) {
|
||||||
{
|
|
||||||
char *delim = ":\n.";
|
char *delim = ":\n.";
|
||||||
char *tokens = strtok(buf, delim);
|
char *tokens = strtok(buf, delim);
|
||||||
while (tokens)
|
while (tokens) {
|
||||||
{
|
|
||||||
char *label = tokens;
|
char *label = tokens;
|
||||||
char *val = strtok(nullptr, delim);
|
char *val = strtok(nullptr, delim);
|
||||||
if (strstr(label, "Pages free"))
|
if (strstr(label, "Pages free")) {
|
||||||
{
|
|
||||||
uint64_t f = stoull(trim(val));
|
uint64_t f = stoull(trim(val));
|
||||||
mem.stats.at("available") = f * 4096;
|
mem.stats.at("available") = f * 4096;
|
||||||
mem.stats.at("free") = f * 4096;
|
mem.stats.at("free") = f * 4096;
|
||||||
mem.stats.at("cached") = 1;
|
mem.stats.at("cached") = 1;
|
||||||
mem.stats.at("used") = Shared::totalMem - (f*4096);
|
mem.stats.at("used") = Shared::totalMem - (f * 4096);
|
||||||
}
|
}
|
||||||
tokens = strtok(nullptr, delim);
|
tokens = strtok(nullptr, delim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pclose(fpIn);
|
pclose(fpIn);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger::error("failed to read vm_stat");
|
Logger::error("failed to read vm_stat");
|
||||||
}
|
}
|
||||||
//? Calculate percentages
|
//? Calculate percentages
|
||||||
for (const auto& name : mem_names) {
|
for (const auto &name : mem_names) {
|
||||||
mem.percent.at(name).push_back(round((double)mem.stats.at(name) * 100 / Shared::totalMem));
|
mem.percent.at(name).push_back(round((double)mem.stats.at(name) * 100 / Shared::totalMem));
|
||||||
while (cmp_greater(mem.percent.at(name).size(), width * 2)) mem.percent.at(name).pop_front();
|
while (cmp_greater(mem.percent.at(name).size(), width * 2)) mem.percent.at(name).pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_disks)
|
if (show_disks) {
|
||||||
{
|
auto &disks = mem.disks;
|
||||||
auto& disks = mem.disks;
|
|
||||||
struct statfs *stfs;
|
struct statfs *stfs;
|
||||||
int count = getmntinfo(&stfs, MNT_WAIT);
|
int count = getmntinfo(&stfs, MNT_WAIT);
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++) {
|
||||||
{
|
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
string mountpoint = stfs[i].f_mntonname;
|
string mountpoint = stfs[i].f_mntonname;
|
||||||
Logger::debug("found mountpoint " + mountpoint);
|
Logger::debug("found mountpoint " + mountpoint);
|
||||||
@ -320,10 +287,9 @@ namespace Mem
|
|||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace Mem
|
||||||
|
|
||||||
namespace Net
|
namespace Net {
|
||||||
{
|
|
||||||
unordered_flat_map<string, net_info> current_net;
|
unordered_flat_map<string, net_info> current_net;
|
||||||
net_info empty_net = {};
|
net_info empty_net = {};
|
||||||
vector<string> interfaces;
|
vector<string> interfaces;
|
||||||
@ -335,25 +301,22 @@ namespace Net
|
|||||||
uint64_t timestamp = 0;
|
uint64_t timestamp = 0;
|
||||||
|
|
||||||
//* RAII wrapper for getifaddrs
|
//* RAII wrapper for getifaddrs
|
||||||
class getifaddr_wrapper
|
class getifaddr_wrapper {
|
||||||
{
|
|
||||||
struct ifaddrs *ifaddr;
|
struct ifaddrs *ifaddr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int status;
|
int status;
|
||||||
getifaddr_wrapper() { status = getifaddrs(&ifaddr); }
|
getifaddr_wrapper() { status = getifaddrs(&ifaddr); }
|
||||||
~getifaddr_wrapper() { freeifaddrs(ifaddr); }
|
~getifaddr_wrapper() { freeifaddrs(ifaddr); }
|
||||||
auto operator()() -> struct ifaddrs * { return ifaddr; }
|
auto operator()() -> struct ifaddrs * { return ifaddr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
auto collect(const bool no_update) -> net_info &
|
auto collect(const bool no_update) -> net_info & {
|
||||||
{
|
|
||||||
return empty_net;
|
return empty_net;
|
||||||
}
|
}
|
||||||
}
|
} // namespace Net
|
||||||
|
|
||||||
namespace Proc
|
namespace Proc {
|
||||||
{
|
|
||||||
|
|
||||||
vector<proc_info> current_procs;
|
vector<proc_info> current_procs;
|
||||||
unordered_flat_map<string, string> uid_user;
|
unordered_flat_map<string, string> uid_user;
|
||||||
@ -372,64 +335,50 @@ namespace Proc
|
|||||||
detail_container detailed;
|
detail_container detailed;
|
||||||
|
|
||||||
//* Generate process tree list
|
//* Generate process tree list
|
||||||
void _tree_gen(proc_info &cur_proc, vector<proc_info> &in_procs, vector<std::reference_wrapper<proc_info>> &out_procs, int cur_depth, const bool collapsed, const string &filter, bool found = false, const bool no_update = false, const bool should_filter = false)
|
void _tree_gen(proc_info &cur_proc, vector<proc_info> &in_procs, vector<std::reference_wrapper<proc_info>> &out_procs, int cur_depth, const bool collapsed, const string &filter, bool found = false, const bool no_update = false, const bool should_filter = false) {
|
||||||
{
|
|
||||||
auto cur_pos = out_procs.size();
|
auto cur_pos = out_procs.size();
|
||||||
bool filtering = false;
|
bool filtering = false;
|
||||||
|
|
||||||
//? If filtering, include children of matching processes
|
//? If filtering, include children of matching processes
|
||||||
if (not found and (should_filter or not filter.empty()))
|
if (not found and (should_filter or not filter.empty())) {
|
||||||
{
|
if (not s_contains(std::to_string(cur_proc.pid), filter) and not s_contains(cur_proc.name, filter) and not s_contains(cur_proc.cmd, filter) and not s_contains(cur_proc.user, filter)) {
|
||||||
if (not s_contains(std::to_string(cur_proc.pid), filter) and not s_contains(cur_proc.name, filter) and not s_contains(cur_proc.cmd, filter) and not s_contains(cur_proc.user, filter))
|
|
||||||
{
|
|
||||||
filtering = true;
|
filtering = true;
|
||||||
cur_proc.filtered = true;
|
cur_proc.filtered = true;
|
||||||
filter_found++;
|
filter_found++;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
found = true;
|
found = true;
|
||||||
cur_depth = 0;
|
cur_depth = 0;
|
||||||
}
|
}
|
||||||
}
|
} else if (cur_proc.filtered)
|
||||||
else if (cur_proc.filtered)
|
|
||||||
cur_proc.filtered = false;
|
cur_proc.filtered = false;
|
||||||
|
|
||||||
//? Set tree index position for process if not filtered out or currently in a collapsed sub-tree
|
//? Set tree index position for process if not filtered out or currently in a collapsed sub-tree
|
||||||
if (not collapsed and not filtering)
|
if (not collapsed and not filtering) {
|
||||||
{
|
|
||||||
out_procs.push_back(std::ref(cur_proc));
|
out_procs.push_back(std::ref(cur_proc));
|
||||||
cur_proc.tree_index = out_procs.size() - 1;
|
cur_proc.tree_index = out_procs.size() - 1;
|
||||||
//? Try to find name of the binary file and append to program name if not the same
|
//? Try to find name of the binary file and append to program name if not the same
|
||||||
if (cur_proc.short_cmd.empty() and not cur_proc.cmd.empty())
|
if (cur_proc.short_cmd.empty() and not cur_proc.cmd.empty()) {
|
||||||
{
|
|
||||||
std::string_view cmd_view = cur_proc.cmd;
|
std::string_view cmd_view = cur_proc.cmd;
|
||||||
cmd_view = cmd_view.substr((size_t)0, min(cmd_view.find(' '), cmd_view.size()));
|
cmd_view = cmd_view.substr((size_t)0, min(cmd_view.find(' '), cmd_view.size()));
|
||||||
cmd_view = cmd_view.substr(min(cmd_view.find_last_of('/') + 1, cmd_view.size()));
|
cmd_view = cmd_view.substr(min(cmd_view.find_last_of('/') + 1, cmd_view.size()));
|
||||||
cur_proc.short_cmd = (string)cmd_view;
|
cur_proc.short_cmd = (string)cmd_view;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
cur_proc.tree_index = in_procs.size();
|
cur_proc.tree_index = in_procs.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
//? Recursive iteration over all children
|
//? Recursive iteration over all children
|
||||||
int children = 0;
|
int children = 0;
|
||||||
for (auto &p : rng::equal_range(in_procs, cur_proc.pid, rng::less{}, &proc_info::ppid))
|
for (auto &p : rng::equal_range(in_procs, cur_proc.pid, rng::less{}, &proc_info::ppid)) {
|
||||||
{
|
if (not no_update and not filtering and (collapsed or cur_proc.collapsed)) {
|
||||||
if (not no_update and not filtering and (collapsed or cur_proc.collapsed))
|
|
||||||
{
|
|
||||||
out_procs.back().get().cpu_p += p.cpu_p;
|
out_procs.back().get().cpu_p += p.cpu_p;
|
||||||
out_procs.back().get().mem += p.mem;
|
out_procs.back().get().mem += p.mem;
|
||||||
out_procs.back().get().threads += p.threads;
|
out_procs.back().get().threads += p.threads;
|
||||||
filter_found++;
|
filter_found++;
|
||||||
}
|
}
|
||||||
if (collapsed and not filtering)
|
if (collapsed and not filtering) {
|
||||||
{
|
|
||||||
cur_proc.filtered = true;
|
cur_proc.filtered = true;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
children++;
|
children++;
|
||||||
_tree_gen(p, in_procs, out_procs, cur_depth + 1, (collapsed ? true : cur_proc.collapsed), filter, found, no_update, should_filter);
|
_tree_gen(p, in_procs, out_procs, cur_depth + 1, (collapsed ? true : cur_proc.collapsed), filter, found, no_update, should_filter);
|
||||||
}
|
}
|
||||||
@ -445,33 +394,27 @@ namespace Proc
|
|||||||
}
|
}
|
||||||
|
|
||||||
//* Get detailed info for selected process
|
//* Get detailed info for selected process
|
||||||
void _collect_details(const size_t pid, const uint64_t uptime, vector<proc_info> &procs)
|
void _collect_details(const size_t pid, const uint64_t uptime, vector<proc_info> &procs) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//* Collects and sorts process information from /proc
|
//* Collects and sorts process information from /proc
|
||||||
auto collect(const bool no_update) -> vector<proc_info> &
|
auto collect(const bool no_update) -> vector<proc_info> & {
|
||||||
{
|
|
||||||
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
|
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
|
||||||
struct kinfo_proc *processes = NULL;
|
struct kinfo_proc *processes = NULL;
|
||||||
const double uptime = system_uptime();
|
const double uptime = system_uptime();
|
||||||
auto procs = ¤t_procs;
|
auto procs = ¤t_procs;
|
||||||
|
|
||||||
for (int retry = 3; retry > 0; retry--)
|
for (int retry = 3; retry > 0; retry--) {
|
||||||
{
|
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0 || size == 0)
|
if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0 || size == 0) {
|
||||||
{
|
|
||||||
Logger::error("Unable to get size of kproc_infos");
|
Logger::error("Unable to get size of kproc_infos");
|
||||||
}
|
}
|
||||||
|
|
||||||
processes = (struct kinfo_proc *)malloc(size);
|
processes = (struct kinfo_proc *)malloc(size);
|
||||||
|
|
||||||
if (sysctl(mib, 4, processes, &size, NULL, 0) == 0)
|
if (sysctl(mib, 4, processes, &size, NULL, 0) == 0) {
|
||||||
{
|
|
||||||
size_t count = size / sizeof(struct kinfo_proc);
|
size_t count = size / sizeof(struct kinfo_proc);
|
||||||
for (size_t i = 0; i < count; i++)
|
for (size_t i = 0; i < count; i++) {
|
||||||
{
|
|
||||||
struct kinfo_proc kproc = processes[i];
|
struct kinfo_proc kproc = processes[i];
|
||||||
Proc::proc_info p{kproc.kp_proc.p_pid};
|
Proc::proc_info p{kproc.kp_proc.p_pid};
|
||||||
char fullname[PROC_PIDPATHINFO_MAXSIZE];
|
char fullname[PROC_PIDPATHINFO_MAXSIZE];
|
||||||
@ -482,8 +425,7 @@ namespace Proc
|
|||||||
p.ppid = kproc.kp_eproc.e_ppid;
|
p.ppid = kproc.kp_eproc.e_ppid;
|
||||||
p.p_nice = kproc.kp_proc.p_nice;
|
p.p_nice = kproc.kp_proc.p_nice;
|
||||||
struct proc_taskinfo pti;
|
struct proc_taskinfo pti;
|
||||||
if (sizeof(pti) == proc_pidinfo(p.pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti)))
|
if (sizeof(pti) == proc_pidinfo(p.pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti))) {
|
||||||
{
|
|
||||||
p.threads = pti.pti_threadnum;
|
p.threads = pti.pti_threadnum;
|
||||||
p.cpu_t = pti.pti_total_user + pti.pti_total_system;
|
p.cpu_t = pti.pti_total_user + pti.pti_total_system;
|
||||||
p.cpu_c = (double)p.cpu_t / max(1.0, (uptime * Shared::clkTck) - p.cpu_s);
|
p.cpu_c = (double)p.cpu_t / max(1.0, (uptime * Shared::clkTck) - p.cpu_s);
|
||||||
@ -498,20 +440,17 @@ namespace Proc
|
|||||||
}
|
}
|
||||||
return current_procs;
|
return current_procs;
|
||||||
}
|
}
|
||||||
}
|
} // namespace Proc
|
||||||
|
|
||||||
namespace Tools
|
namespace Tools {
|
||||||
{
|
double system_uptime() {
|
||||||
double system_uptime()
|
|
||||||
{
|
|
||||||
struct timeval ts, currTime;
|
struct timeval ts, currTime;
|
||||||
std::size_t len = sizeof(ts);
|
std::size_t len = sizeof(ts);
|
||||||
int mib[2] = {CTL_KERN, KERN_BOOTTIME};
|
int mib[2] = {CTL_KERN, KERN_BOOTTIME};
|
||||||
if (sysctl(mib, 2, &ts, &len, NULL, 0) != -1)
|
if (sysctl(mib, 2, &ts, &len, NULL, 0) != -1) {
|
||||||
{
|
|
||||||
gettimeofday(&currTime, NULL);
|
gettimeofday(&currTime, NULL);
|
||||||
return currTime.tv_sec - ts.tv_sec;
|
return currTime.tv_sec - ts.tv_sec;
|
||||||
}
|
}
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
}
|
} // namespace Tools
|
Loading…
Reference in New Issue
Block a user