Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Share common code from collect #756

Merged
merged 3 commits into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion src/btop_shared.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,19 @@ tab-size = 4
#include <string>
#include <tuple>
#include <vector>
#include <ifaddrs.h>
#include <unordered_map>
#include <unistd.h>

// From `man 3 getifaddrs`: <net/if.h> must be included before <ifaddrs.h>
// clang-format off
#include <net/if.h>
#include <ifaddrs.h>
// clang-format on

#if defined(__FreeBSD__) || defined(__OpenBSD__)
# include <kvm.h>
#endif

using std::array;
using std::atomic;
using std::deque;
Expand Down Expand Up @@ -83,6 +92,15 @@ namespace Shared {
void init();

extern long coreCount, page_size, clk_tck;

#if defined(__FreeBSD__) || defined(__OpenBSD__)
struct KvmDeleter {
void operator()(kvm_t* handle) {
kvm_close(handle);
}
};
using KvmPtr = std::unique_ptr<kvm_t, KvmDeleter>;
#endif
}


Expand Down Expand Up @@ -289,6 +307,17 @@ namespace Net {
bool connected{};
};

class IfAddrsPtr {
struct ifaddrs* ifaddr;
int status;
public:
IfAddrsPtr() { status = getifaddrs(&ifaddr); }
~IfAddrsPtr() { freeifaddrs(ifaddr); }
[[nodiscard]] constexpr auto operator()() -> struct ifaddrs* { return ifaddr; }
[[nodiscard]] constexpr auto get() -> struct ifaddrs* { return ifaddr; }
[[nodiscard]] constexpr auto get_status() const noexcept -> int { return status; };
};

extern std::unordered_map<string, net_info> current_net;

//* Collect net upload/download stats
Expand Down
41 changes: 9 additions & 32 deletions src/freebsd/btop_collect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,18 +189,6 @@ namespace Shared {
Logger::debug("Init -> Mem::get_zpools()");
Mem::get_zpools();
}

//* RAII wrapper for kvm_openfiles
class kvm_openfiles_wrapper {
kvm_t* kd = nullptr;
public:
kvm_openfiles_wrapper(const char* execf, const char* coref, const char* swapf, int flags, char* err) {
this->kd = kvm_openfiles(execf, coref, swapf, flags, err);
}
~kvm_openfiles_wrapper() { kvm_close(kd); }
auto operator()() -> kvm_t* { return kd; }
};

} // namespace Shared

namespace Cpu {
Expand Down Expand Up @@ -673,9 +661,9 @@ namespace Mem {

if (show_swap) {
char buf[_POSIX2_LINE_MAX];
Shared::kvm_openfiles_wrapper kd(nullptr, _PATH_DEVNULL, nullptr, O_RDONLY, buf);
Shared::KvmPtr kd {kvm_openfiles(nullptr, _PATH_DEVNULL, nullptr, O_RDONLY, buf)};
struct kvm_swap swap[16];
int nswap = kvm_getswapinfo(kd(), swap, 16, 0);
int nswap = kvm_getswapinfo(kd.get(), swap, 16, 0);
int totalSwap = 0, usedSwap = 0;
for (int i = 0; i < nswap; i++) {
totalSwap += swap[i].ksw_total;
Expand Down Expand Up @@ -828,17 +816,6 @@ namespace Net {
bool rescale = true;
uint64_t timestamp = 0;

//* RAII wrapper for getifaddrs
class getifaddr_wrapper {
struct ifaddrs *ifaddr;

public:
int status;
getifaddr_wrapper() { status = getifaddrs(&ifaddr); }
~getifaddr_wrapper() { freeifaddrs(ifaddr); }
auto operator()() -> struct ifaddrs * { return ifaddr; }
};

auto collect(bool no_update) -> net_info & {
auto &net = current_net;
auto &config_iface = Config::getS("net_iface");
Expand All @@ -848,10 +825,10 @@ namespace Net {

if (not no_update and errors < 3) {
//? Get interface list using getifaddrs() wrapper
getifaddr_wrapper if_wrap{};
if (if_wrap.status != 0) {
IfAddrsPtr if_addrs {};
if (if_addrs.get_status() != 0) {
errors++;
Logger::error("Net::collect() -> getifaddrs() failed with id " + to_string(if_wrap.status));
Logger::error("Net::collect() -> getifaddrs() failed with id " + to_string(if_addrs.get_status()));
redraw = true;
return empty_net;
}
Expand All @@ -863,7 +840,7 @@ namespace Net {
string ipv4, ipv6;

//? Iteration over all items in getifaddrs() list
for (auto *ifa = if_wrap(); ifa != nullptr; ifa = ifa->ifa_next) {
for (auto *ifa = if_addrs.get(); ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr) continue;
family = ifa->ifa_addr->sa_family;
const auto &iface = ifa->ifa_name;
Expand Down Expand Up @@ -1169,8 +1146,8 @@ namespace Proc {

int count = 0;
char buf[_POSIX2_LINE_MAX];
Shared::kvm_openfiles_wrapper kd(nullptr, _PATH_DEVNULL, nullptr, O_RDONLY, buf);
const struct kinfo_proc* kprocs = kvm_getprocs(kd(), KERN_PROC_PROC, 0, &count);
Shared::KvmPtr kd {kvm_openfiles(nullptr, _PATH_DEVNULL, nullptr, O_RDONLY, buf)};
const struct kinfo_proc* kprocs = kvm_getprocs(kd.get(), KERN_PROC_PROC, 0, &count);

for (int i = 0; i < count; i++) {
const struct kinfo_proc* kproc = &kprocs[i];
Expand All @@ -1197,7 +1174,7 @@ namespace Proc {
continue;
}
new_proc.name = kproc->ki_comm;
char** argv = kvm_getargv(kd(), kproc, 0);
char** argv = kvm_getargv(kd.get(), kproc, 0);
if (argv) {
for (int i = 0; argv[i] and cmp_less(new_proc.cmd.size(), 1000); i++) {
new_proc.cmd += argv[i] + " "s;
Expand Down
18 changes: 4 additions & 14 deletions src/linux/btop_collect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2197,16 +2197,6 @@ namespace Net {
bool rescale{true};
uint64_t timestamp{};

//* RAII wrapper for getifaddrs
class getifaddr_wrapper {
struct ifaddrs* ifaddr;
public:
int status;
getifaddr_wrapper() { status = getifaddrs(&ifaddr); }
~getifaddr_wrapper() { freeifaddrs(ifaddr); }
auto operator()() -> struct ifaddrs* { return ifaddr; }
};

auto collect(bool no_update) -> net_info& {
if (Runner::stopping) return empty_net;
auto& net = current_net;
Expand All @@ -2217,10 +2207,10 @@ namespace Net {

if (not no_update and errors < 3) {
//? Get interface list using getifaddrs() wrapper
getifaddr_wrapper if_wrap {};
if (if_wrap.status != 0) {
IfAddrsPtr if_addrs {};
if (if_addrs.get_status() != 0) {
errors++;
Logger::error("Net::collect() -> getifaddrs() failed with id " + to_string(if_wrap.status));
Logger::error("Net::collect() -> getifaddrs() failed with id " + to_string(if_addrs.get_status()));
redraw = true;
return empty_net;
}
Expand All @@ -2232,7 +2222,7 @@ namespace Net {
string ipv4, ipv6;

//? Iteration over all items in getifaddrs() list
for (auto* ifa = if_wrap(); ifa != nullptr; ifa = ifa->ifa_next) {
for (auto* ifa = if_addrs.get(); ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr) continue;
family = ifa->ifa_addr->sa_family;
const auto& iface = ifa->ifa_name;
Expand Down
37 changes: 7 additions & 30 deletions src/openbsd/btop_collect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,18 +184,6 @@ namespace Shared {
Mem::old_uptime = system_uptime();
Mem::collect();
}

//* RAII wrapper for kvm_openfiles
class kvm_openfiles_wrapper {
kvm_t* kd = nullptr;
public:
kvm_openfiles_wrapper(const char* execf, const char* coref, const char* swapf, int flags, char* err) {
this->kd = kvm_openfiles(execf, coref, swapf, flags, err);
}
~kvm_openfiles_wrapper() { kvm_close(kd); }
auto operator()() -> kvm_t* { return kd; }
};

} // namespace Shared

namespace Cpu {
Expand Down Expand Up @@ -780,17 +768,6 @@ namespace Net {
bool rescale = true;
uint64_t timestamp = 0;

//* RAII wrapper for getifaddrs
class getifaddr_wrapper {
struct ifaddrs *ifaddr;

public:
int status;
getifaddr_wrapper() { status = getifaddrs(&ifaddr); }
~getifaddr_wrapper() { freeifaddrs(ifaddr); }
auto operator()() -> struct ifaddrs * { return ifaddr; }
};

auto collect(bool no_update) -> net_info & {
auto &net = current_net;
auto &config_iface = Config::getS("net_iface");
Expand All @@ -800,10 +777,10 @@ namespace Net {

if (not no_update and errors < 3) {
//? Get interface list using getifaddrs() wrapper
getifaddr_wrapper if_wrap{};
if (if_wrap.status != 0) {
IfAddrsPtr if_addrs {};
if (if_addrs.get_status() != 0) {
errors++;
Logger::error("Net::collect() -> getifaddrs() failed with id " + to_string(if_wrap.status));
Logger::error("Net::collect() -> getifaddrs() failed with id " + to_string(if_addrs.get_status()));
redraw = true;
return empty_net;
}
Expand All @@ -815,7 +792,7 @@ namespace Net {
string ipv4, ipv6;

//? Iteration over all items in getifaddrs() list
for (auto *ifa = if_wrap(); ifa != nullptr; ifa = ifa->ifa_next) {
for (auto *ifa = if_addrs.get(); ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr) continue;
family = ifa->ifa_addr->sa_family;
const auto &iface = ifa->ifa_name;
Expand Down Expand Up @@ -1102,8 +1079,8 @@ namespace Proc {

int count = 0;
char buf[_POSIX2_LINE_MAX];
Shared::kvm_openfiles_wrapper kd(nullptr, nullptr, nullptr, KVM_NO_FILES, buf);
const struct kinfo_proc* kprocs = kvm_getprocs(kd(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &count);
Shared::KvmPtr kd {kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, buf)};
const struct kinfo_proc* kprocs = kvm_getprocs(kd.get() , KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &count);

for (int i = 0; i < count; i++) {
const struct kinfo_proc* kproc = &kprocs[i];
Expand All @@ -1130,7 +1107,7 @@ namespace Proc {
continue;
}
new_proc.name = kproc->p_comm;
char** argv = kvm_getargv(kd(), kproc, 0);
char** argv = kvm_getargv(kd.get(), kproc, 0);
if (argv) {
for (int i = 0; argv[i] and cmp_less(new_proc.cmd.size(), 1000); i++) {
new_proc.cmd += argv[i] + " "s;
Expand Down
Loading