Added signal handler

This commit is contained in:
aristocratos 2021-06-09 19:47:49 +02:00
parent dbb5a0599b
commit 10a8bfe39e
7 changed files with 78 additions and 28 deletions

View File

@ -4,7 +4,7 @@ CPP = g++
override CPPFLAGS += -std=c++20 -pthread
OPTFLAG = -O3
INFOFLAGS += -Wall -Wextra -Wno-stringop-overread -pedantic
INCLUDES = -I./src -I./include
INCLUDES = -Isrc -Iinclude
btop: btop.cpp
@mkdir -p bin

View File

@ -21,6 +21,7 @@ tab-size = 4
#include <array>
#include <list>
#include <vector>
#include <csignal>
#include <thread>
#include <future>
#include <atomic>
@ -51,7 +52,7 @@ namespace Global {
#include <btop_menu.h>
#if defined(__linux__)
#define LINUX 1
#define LINUX
#include <btop_linux.h>
#elif defined(__unix__) || !defined(__APPLE__) && defined(__MACH__)
#include <sys/param.h>
@ -62,7 +63,7 @@ namespace Global {
#elif defined(__APPLE__) && defined(__MACH__)
#include <TargetConditionals.h>
#if TARGET_OS_MAC == 1
#define OSX 1
#define OSX
// #include <btop_osx.h>
#error OSX support not yet implemented!
#endif
@ -113,7 +114,7 @@ void argumentParser(int argc, char **argv){
}
}
void clean_quit(int signal){
void clean_quit(int sig){
if (Global::quitting) return;
if (Term::initialized) {
Term::restore();
@ -121,11 +122,39 @@ void clean_quit(int signal){
}
if (Global::debug) Logger::debug("Quitting! Runtime: " + sec_to_dhms(time_s() - Global::start_time));
Global::quitting = true;
if (signal != -1) exit(signal);
Config::write();
if (sig != -1) exit(sig);
}
void sleep_now(){
if (Term::initialized) {
Term::restore();
if (!Global::debuginit) cout << Term::normal_screen << Term::show_cursor << flush;
}
std::raise(SIGSTOP);
}
void resume_now(){
Term::init();
if (!Global::debuginit) cout << Term::alt_screen << Term::hide_cursor << flush;
}
void _exit_handler() { clean_quit(-1); }
void _signal_handler(int sig) {
switch (sig) {
case SIGINT:
clean_quit(0);
break;
case SIGTSTP:
sleep_now();
break;
case SIGCONT:
resume_now();
break;
}
}
//? Generate the btop++ banner
void banner_gen() {
size_t z = 0;
@ -178,11 +207,16 @@ int main(int argc, char **argv){
if (argc > 1) argumentParser(argc, argv);
std::atexit(_exit_handler);
std::at_quick_exit(_exit_handler);
std::signal(SIGINT, _signal_handler);
std::signal(SIGTSTP, _signal_handler);
std::signal(SIGCONT, _signal_handler);
//? Linux init
#if defined(LINUX)
Global::coreCount = sysconf(_SC_NPROCESSORS_ONLN);
if (Global::coreCount < 1) Global::coreCount = 1;
{
std::error_code ec;
Global::self_path = fs::read_symlink("/proc/self/exe", ec).remove_filename();
@ -261,7 +295,7 @@ int main(int argc, char **argv){
//* ------------------------------------------------ TESTING ------------------------------------------------------
Global::debuginit = false;
Global::debuginit = true;
// cout << Theme("main_bg") << Term::clear << flush;
// bool thread_test = false;
@ -453,8 +487,8 @@ int main(int argc, char **argv){
greyscale.push_back(Theme::dec_to_color(xc, xc, xc));
}
string pbox = Draw::createBox({.x = 0, .y = 10, .width = Term::width, .height = Term::height - 16, .line_color = Theme::c("proc_box"), .title = "testbox", .title2 = "below", .fill = false, .num = 7});
pbox += rjust("Pid:", 8) + " " + ljust("Program:", 16) + " " + ljust("Command:", Term::width - 69) + " Threads: " +
string pbox = Draw::createBox({.x = 1, .y = 10, .width = Term::width, .height = Term::height - 16, .line_color = Theme::c("proc_box"), .title = "testbox", .title2 = "below", .fill = false, .num = 7});
pbox += Mv::r(1) + rjust("Pid:", 8) + " " + ljust("Program:", 16) + " " + ljust("Command:", Term::width - 70) + " Threads: " +
ljust("User:", 10) + " " + rjust("MemB", 5) + " " + rjust("Cpu%", 14) + "\n" + Mv::save;
while (key != "q") {

View File

@ -40,7 +40,7 @@ namespace Config {
atomic<bool> locked (false);
atomic<bool> writelock (false);
bool changed = false;
unordered_flat_map<string, bool> changed;
unordered_flat_map<string, string> strings = {
{"color_theme", "Default"},
@ -104,23 +104,22 @@ namespace Config {
bool _locked(){
atomic_wait(writelock);
if (!changed) changed = true;
return locked.load();
}
}
//* Return config value <name> as a bool
bool& getB(string name){
//* Return bool config value <name>
const bool& getB(string name){
return bools.at(name);
}
//* Return config value <name> as a int
int& getI(string name){
//* Return integer config value <name>
const int& getI(string name){
return ints.at(name);
}
//* Return config value <name> as a string
string& getS(string name){
//* Return string config value <name>
const string& getS(string name){
return strings.at(name);
}
@ -128,18 +127,21 @@ namespace Config {
void set(string name, bool value){
if (_locked()) boolsTmp.insert_or_assign(name, value);
else bools.at(name) = value;
changed.insert_or_assign(name, true);
}
//* Set config value <name> to int <value>
void set(string name, int value){
if (_locked()) intsTmp.insert_or_assign(name, value);
ints.at(name) = value;
changed.insert_or_assign(name, true);
}
//* Set config value <name> to string <value>
void set(string name, string value){
if (_locked()) stringsTmp.insert_or_assign(name, value);
else strings.at(name) = value;
changed.insert_or_assign(name, true);
}
//* Flip config bool <name>
@ -149,6 +151,7 @@ namespace Config {
else boolsTmp.insert_or_assign(name, (!bools.at(name)));
}
else bools.at(name) = !bools.at(name);
changed.insert_or_assign(name, true);
}
//* Wait if locked then lock config and cache changes until unlock
@ -184,6 +187,19 @@ namespace Config {
void load(){
if (conf_file.empty()) return;
}
void write(){
if (conf_file.empty() || changed.empty()) return;
if (Logger::loglevel > 3) {
string items;
for (auto item : Config::changed) {
items += item.first + ", ";
}
items.pop_back(); items.pop_back();
Logger::debug("Writing out new config values for: " + items);
}
}
}
#endif

View File

@ -91,21 +91,21 @@ namespace Draw {
//* Draw horizontal lines
for (uint hpos : {c.y, c.y + c.height - 1}){
out += Mv::to(hpos, c.x) + Symbols::h_line * (c.width);
out += Mv::to(hpos, c.x) + Symbols::h_line * (c.width - 1);
}
//* Draw vertical lines and fill if enabled
for (uint hpos : iota(c.y + 1, c.y + c.height - 1)){
out += Mv::to(hpos, c.x) + Symbols::v_line +
((c.fill) ? string(c.width - 1, ' ') : Mv::r(c.width - 1)) +
((c.fill) ? string(c.width - 2, ' ') : Mv::r(c.width - 2)) +
Symbols::v_line;
}
//* Draw corners
out += Mv::to(c.y, c.x) + Symbols::left_up +
Mv::to(c.y, c.x + c.width) + Symbols::right_up +
Mv::to(c.y, c.x + c.width - 1) + Symbols::right_up +
Mv::to(c.y + c.height - 1, c.x) + Symbols::left_down +
Mv::to(c.y + c.height - 1, c.x + c.width) + Symbols::right_down;
Mv::to(c.y + c.height - 1, c.x + c.width - 1) + Symbols::right_down;
//* Draw titles if defined
if (!c.title.empty()){
@ -117,7 +117,7 @@ namespace Draw {
Fx::ub + lcolor + Symbols::title_right;
}
return out + Fx::reset + Mv::to(c.y + 1, c.x + 2);
return out + Fx::reset + Mv::to(c.y + 1, c.x + 1);
}
//* Class holding a percentage meter

View File

@ -155,8 +155,8 @@ namespace Proc {
return current_procs;
}
string pid_str = d.path().filename();
bool new_cache = false;
string pid_str = d.path().filename();
if (d.is_directory() && isdigit(pid_str[0])) {
npids++;
proc_info new_proc (stoul(pid_str));
@ -314,7 +314,7 @@ namespace Proc {
);
//* When using "cpu lazy" sorting push processes with high cpu usage to the front regardless of cumulative usage
if (sort_map.at(sorting) == 7 && !reverse) {
if (sorting == "cpu lazy" && !reverse) {
double max = 10.0, target = 30.0;
for (size_t i = 0, offset = 0; i < procs.size(); i++) {
if (i <= 5 && procs[i].cpu_p > max) max = procs[i].cpu_p;

View File

@ -257,7 +257,7 @@ namespace Theme {
//? If only _start was defined fill array with _start color
c_gradient.fill(colors[name]);
}
gradients[wname] = c_gradient;
gradients[wname].swap(c_gradient);
}
}
}

View File

@ -267,8 +267,8 @@ namespace Tools {
return (str == "true") || (str == "false") || (str == "True") || (str == "False");
}
//* Check if a string is a valid integer value
bool isint(string& str){
//* Check if a string is a valid positive integer value
bool isuint(string& str){
return all_of(str.begin(), str.end(), ::isdigit);
}
@ -428,13 +428,13 @@ namespace Tools {
}
#if __GNUC__ > 10
#if (__GNUC__ > 10)
//* Redirects to atomic wait
void atomic_wait(atomic<bool>& atom, bool val=true){
atom.wait(val);
}
#else
//* Crude implementation of atomic wait for GCC < 11
//* Crude implementation of atomic wait for GCC 10
void atomic_wait(atomic<bool>& atom, bool val=true){
while (atom.load() == val) sleep_ms(1);
}