diff options
-rw-r--r-- | .github/workflows/continuous-build.yml | 119 | ||||
-rw-r--r-- | .gitignore | 6 | ||||
-rw-r--r-- | CHANGELOG.md | 10 | ||||
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | snap/snapcraft.yaml | 15 | ||||
-rw-r--r-- | src/btop_draw.cpp | 10 | ||||
-rw-r--r-- | src/btop_shared.hpp | 5 | ||||
-rw-r--r-- | src/linux/btop_collect.cpp | 90 | ||||
-rw-r--r-- | src/osx/btop_collect.cpp | 5 |
10 files changed, 221 insertions, 51 deletions
diff --git a/.github/workflows/continuous-build.yml b/.github/workflows/continuous-build.yml new file mode 100644 index 0000000..91392c0 --- /dev/null +++ b/.github/workflows/continuous-build.yml @@ -0,0 +1,119 @@ +name: Continuous Build Linux + +on: + push: + paths: + - 'src/**' + - '!src/osx/**' + - '!src/freebsd/**' + - 'include/**' + - 'Makefile' + - '.github/workflows/continuous-build.yml' + +jobs: + build: + + runs-on: ubuntu-latest + container: ubuntu:21.04 + + steps: + - uses: actions/checkout@v2 + - name: Install build tools + run: | + apt update && \ + apt install coreutils sed git build-essential gcc-11 g++-11 -y + apt install -y g++-11-aarch64-linux-gnu g++-11-i686-linux-gnu \ + g++-11-arm-linux-gnueabi g++-11-arm-linux-gnueabihf g++-11-riscv64-linux-gnu \ + g++-11-sparc64-linux-gnu + + mkdir -p multiarch_bin + + git init # [fix Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).] + + - name: Compile x86_64 + run: | + make CXX=g++-11 ARCH=x86_64 STATIC=true QUIET=true + GIT_HASH=$(git rev-parse --short "$GITHUB_SHA") + mv bin/btop multiarch_bin/btop-x86_64-$GIT_HASH + make distclean + + - name: Compile i686 + run: | + make CXX=i686-linux-gnu-g++-11 ARCH=i686 STATIC=true QUIET=true + GIT_HASH=$(git rev-parse --short "$GITHUB_SHA") + mv bin/btop multiarch_bin/btop-i686-$GIT_HASH + make distclean + + - name: Compile aarch64 + run: | + make CXX=aarch64-linux-gnu-g++-11 ARCH=aarch64 STATIC=true QUIET=true + GIT_HASH=$(git rev-parse --short "$GITHUB_SHA") + mv bin/btop multiarch_bin/btop-aarch64-$GIT_HASH + make distclean + + - name: Compile armel + run: | + make CXX=arm-linux-gnueabi-g++-11 ARCH=armel STATIC=true QUIET=true + GIT_HASH=$(git rev-parse --short "$GITHUB_SHA") + mv bin/btop multiarch_bin/btop-armel-$GIT_HASH + make distclean + + - name: Compile armhf + run: | + make CXX=arm-linux-gnueabihf-g++-11 ARCH=armhf STATIC=true QUIET=true + GIT_HASH=$(git rev-parse --short "$GITHUB_SHA") + mv bin/btop multiarch_bin/btop-armhf-$GIT_HASH + make distclean + + - name: Compile riscv64 + run: | + make CXX=riscv64-linux-gnu-g++-11 ARCH=riscv64 STATIC=true QUIET=true + GIT_HASH=$(git rev-parse --short "$GITHUB_SHA") + mv bin/btop multiarch_bin/btop-riscv64-$GIT_HASH + make distclean + + - name: Compile sparc64 + run: | + make CXX=sparc64-linux-gnu-g++-11 ARCH=sparc64 STATIC=true QUIET=true + GIT_HASH=$(git rev-parse --short "$GITHUB_SHA") + mv bin/btop multiarch_bin/btop-sparc64-$GIT_HASH + make distclean + + - name: Make executable + run: | + chmod +x multiarch_bin/* + + - uses: actions/upload-artifact@v2 + with: + name: btop-x86_64 + path: 'multiarch_bin/btop-x86_64*' + + - uses: actions/upload-artifact@v2 + with: + name: btop-i686 + path: 'multiarch_bin/btop-i686*' + + - uses: actions/upload-artifact@v2 + with: + name: btop-aarch64 + path: 'multiarch_bin/btop-aarch64*' + + - uses: actions/upload-artifact@v2 + with: + name: btop-armel + path: 'multiarch_bin/btop-armel*' + + - uses: actions/upload-artifact@v2 + with: + name: btop-armhf + path: 'multiarch_bin/btop-armhf*' + + - uses: actions/upload-artifact@v2 + with: + name: btop-riscv64 + path: 'multiarch_bin/btop-riscv64*' + + - uses: actions/upload-artifact@v2 + with: + name: btop-sparc64 + path: 'multiarch_bin/btop-sparc64*' @@ -49,4 +49,8 @@ stage/ build bin btop -.*/
\ No newline at end of file +.*/ + + +#do not ignore .github directory +!.github
\ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index b4fec24..4e51591 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## v1.0.14 (next release) + +* Changed: Total system memory is checked at every update instead of once at start + +* Added: Continuous Build workflow, by @ShrirajHegde + +* Fixed: Uid -> User fallback to getpwuid() if failure for non static builds + +* Fixed: snap root disk and changed to compiler flags instead of env variables for detection + ## v1.0.13 * Changed: Graph empty symbol is now regular whitespace @@ -6,7 +6,7 @@ override BTOP_VERSION := $(shell head -n100 src/btop.cpp 2>/dev/null | grep "Ver override TIMESTAMP := $(shell date +%s 2>/dev/null || echo "0") ifneq ($(QUIET),true) - override PRE := info + override PRE := info info-quiet override QUIET := false else override PRE := info-quiet @@ -24,7 +24,7 @@ ifeq ($(ARCH),x86_64) endif ifeq ($(STATIC),true) - override ADDFLAGS += -static -static-libgcc -static-libstdc++ + override ADDFLAGS += -D STATIC_BUILD -static -static-libgcc -static-libstdc++ endif #? Make sure PLATFORM Darwin is OSX and not Darwin @@ -124,8 +124,6 @@ info: @printf "\033[1;95mCXXFLAGS \033[1;92m+| \033[0;37m\$$(\033[92mREQFLAGS\033[37m) \$$(\033[93mLDCXXFLAGS\033[37m) \$$(\033[94mOPTFLAGS\033[37m) \$$(\033[91mWARNFLAGS\033[37m)\n" @printf "\033[1;95mLDFLAGS \033[1;92m+| \033[0;37m\$$(\033[93mLDCXXFLAGS\033[37m) \$$(\033[94mOPTFLAGS\033[37m) \$$(\033[91mWARNFLAGS\033[37m)\n" - @printf "\n\033[1;92mBuilding btop++ \033[93m(\033[97mv$(BTOP_VERSION)\033[93m)\033[0m\n" - info-quiet: @printf "\n\033[1;92mBuilding btop++ \033[91m(\033[97mv$(BTOP_VERSION)\033[91m) \033[93m$(PLATFORM) \033[96m$(ARCH)\033[0m\n" @@ -143,6 +141,7 @@ ifneq ($(PLATFORM),OSX) @printf " setuid Set installed binary owner/group to \$$SU_USER/\$$SU_GROUP ($(SU_USER)/$(SU_GROUP)) and set SUID bit\n" endif @printf " uninstall Uninstall btop++ from \$$PREFIX\n" + @printf " info Display information about Environment,compiler and linker flags\n" #? Make the Directories directories: @@ -12,6 +12,9 @@ [![Sponsor](https://img.shields.io/badge/-Sponsor-red?logo=github)](https://github.com/sponsors/aristocratos) [![Coffee](https://img.shields.io/badge/-Buy%20me%20a%20Coffee-grey?logo=Ko-fi)](https://ko-fi.com/aristocratos) [![btop](https://snapcraft.io/btop/badge.svg)](https://snapcraft.io/btop) +[![Continuous Build](https://github.com/aristocratos/btop/actions/workflows/continuous-build.yml/badge.svg)](https://github.com/aristocratos/btop/actions) + + ## Index @@ -247,6 +250,8 @@ Also needs a UTF8 locale and a font that covers: Append `STATIC=true` to `make` command for static compilation. + Notice! If using LDAP Authentication, usernames will show as UID number for LDAP users when compiling statically. + Append `QUIET=true` for less verbose output. Notice! Manually set `$ARCH` variable if cross-compiling diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 0662db5..17d75ed 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -7,9 +7,6 @@ description: | license: Apache-2.0 -assumes: - - command-chain - base: core20 grade: stable confinement: strict @@ -29,12 +26,9 @@ package-repositories: apps: btop: command: usr/local/bin/btop - command-chain: - - bin/homeishome-launch environment: LC_ALL: C.UTF-8 LANG: C.UTF-8 - BTOP_SNAPPED: true plugs: - mount-observe - process-control @@ -53,6 +47,8 @@ parts: make-parameters: - PREFIX=/usr/local - STATIC=true + - ADDFLAGS="-D SNAPPED" + build-packages: - coreutils - sed @@ -60,12 +56,7 @@ parts: - build-essential - gcc-11 - g++-11 + override-pull: | snapcraftctl pull snapcraftctl set-version "$(git describe --tags | sed 's/^v//' | cut -d "-" -f1)" - - homeishome-launch: - plugin: nil - stage-snaps: - - homeishome-launch - diff --git a/src/btop_draw.cpp b/src/btop_draw.cpp index 0f1f93e..2f3eabc 100644 --- a/src/btop_draw.cpp +++ b/src/btop_draw.cpp @@ -698,6 +698,7 @@ namespace Mem { auto& tty_mode = Config::getB("tty_mode"); auto& graph_symbol = (tty_mode ? "tty" : Config::getS("graph_symbol_mem")); auto& graph_bg = Symbols::graph_symbols.at((graph_symbol == "default" ? Config::getS("graph_symbol") + "_up" : graph_symbol + "_up")).at(6); + auto totalMem = Mem::get_totalMem(); string out; out.reserve(height * width); @@ -791,7 +792,7 @@ namespace Mem { string up = (graph_height >= 2 ? Mv::l(mem_width - 2) + Mv::u(graph_height - 1) : ""); bool big_mem = mem_width > 21; - out += Mv::to(y + 1, x + 2) + Theme::c("title") + Fx::b + "Total:" + rjust(floating_humanizer(Shared::totalMem), mem_width - 9) + Fx::ub + Theme::c("main_fg"); + out += Mv::to(y + 1, x + 2) + Theme::c("title") + Fx::b + "Total:" + rjust(floating_humanizer(totalMem), mem_width - 9) + Fx::ub + Theme::c("main_fg"); vector<string> comb_names (mem_names.begin(), mem_names.end()); if (show_swap and has_swap and not swap_disk) comb_names.insert(comb_names.end(), swap_names.begin(), swap_names.end()); for (auto name : comb_names) { @@ -1107,6 +1108,7 @@ namespace Proc { const int y = show_detailed ? Proc::y + 8 : Proc::y; const int height = show_detailed ? Proc::height - 8 : Proc::height; const int select_max = show_detailed ? Proc::select_max - 8 : Proc::select_max; + auto totalMem = Mem::get_totalMem(); int numpids = Proc::numpids; if (force_redraw) redraw = true; string out; @@ -1312,7 +1314,7 @@ namespace Proc { if (item_fit >= 8) out += cjust(to_string(detailed.entry.p_nice), item_width); - const double mem_p = (double)detailed.mem_bytes.back() * 100 / Shared::totalMem; + const double mem_p = (double)detailed.mem_bytes.back() * 100 / totalMem; string mem_str = to_string(mem_p); mem_str.resize((mem_p < 10 or mem_p >= 100 ? 3 : 4)); out += Mv::to(d_y + 4, d_x + 1) + Theme::c("title") + Fx::b + rjust((item_fit > 4 ? "Memory: " : "M:") + mem_str + "% ", (d_width / 3) - 2) @@ -1370,7 +1372,7 @@ namespace Proc { if (proc_colors) { end = Theme::c("main_fg") + Fx::ub; array<string, 3> colors; - for (int i = 0; int v : {(int)round(p.cpu_p), (int)round(p.mem * 100 / Shared::totalMem), (int)p.threads / 3}) { + for (int i = 0; int v : {(int)round(p.cpu_p), (int)round(p.mem * 100 / totalMem), (int)p.threads / 3}) { if (proc_gradient) { int val = (min(v, 100) + 100) - calc * 100 / select_max; if (val < 100) colors[i++] = Theme::g("proc_color").at(max(0, val)); @@ -1424,7 +1426,7 @@ namespace Proc { } string mem_str = (mem_bytes ? floating_humanizer(p.mem, true) : ""); if (not mem_bytes) { - double mem_p = clamp((double)p.mem * 100 / Shared::totalMem, 0.0, 100.0); + double mem_p = clamp((double)p.mem * 100 / totalMem, 0.0, 100.0); mem_str = to_string(mem_p); if (mem_str.size() < 4) mem_str = "0"; else mem_str.resize((mem_p < 10 or mem_p >= 100 ? 3 : 4)); diff --git a/src/btop_shared.hpp b/src/btop_shared.hpp index 4d0f323..832208c 100644 --- a/src/btop_shared.hpp +++ b/src/btop_shared.hpp @@ -70,8 +70,6 @@ namespace Shared { void init(); extern long coreCount, page_size, clk_tck; - extern int totalMem_len; - extern uint64_t totalMem; } @@ -149,6 +147,9 @@ namespace Mem { vector<string> disks_order; }; + //?* Get total system memory + uint64_t get_totalMem(); + //* Collect mem & disks stats auto collect(const bool no_update=false) -> mem_info&; diff --git a/src/linux/btop_collect.cpp b/src/linux/btop_collect.cpp index 56730e7..ff72654 100644 --- a/src/linux/btop_collect.cpp +++ b/src/linux/btop_collect.cpp @@ -27,6 +27,10 @@ tab-size = 4 #include <ifaddrs.h> #include <net/if.h> +#ifndef STATIC_BUILD + #include <pwd.h> +#endif + #include <btop_shared.hpp> #include <btop_config.hpp> #include <btop_tools.hpp> @@ -78,9 +82,7 @@ namespace Mem { namespace Shared { fs::path procPath, passwd_path; - uint64_t totalMem; long pageSize, clkTck, coreCount; - int totalMem_len; void init() { @@ -110,17 +112,7 @@ namespace Shared { clkTck = 100; Logger::warning("Could not get system clock ticks per second. Defaulting to 100, processes cpu usage might be incorrect."); } - - ifstream meminfo(Shared::procPath / "meminfo"); - if (meminfo.good()) { - meminfo.ignore(SSmax, ':'); - meminfo >> totalMem; - totalMem_len = to_string(totalMem).size(); - totalMem <<= 10; - } - if (not meminfo.good() or totalMem == 0) - throw std::runtime_error("Could not get total memory size from /proc/meminfo"); - + //? Init for namespace Cpu if (not fs::exists(Cpu::freq_path) or access(Cpu::freq_path.c_str(), R_OK) == -1) Cpu::freq_path.clear(); Cpu::current_cpu.core_percent.insert(Cpu::current_cpu.core_percent.begin(), Shared::coreCount, {}); @@ -673,13 +665,27 @@ namespace Mem { mem_info current_mem {}; + uint64_t get_totalMem() { + ifstream meminfo(Shared::procPath / "meminfo"); + int64_t totalMem; + if (meminfo.good()) { + meminfo.ignore(SSmax, ':'); + meminfo >> totalMem; + totalMem <<= 10; + } + if (not meminfo.good() or totalMem == 0) + throw std::runtime_error("Could not get total memory size from /proc/meminfo"); + + return totalMem; + } + auto collect(const bool no_update) -> mem_info& { if (Runner::stopping or (no_update and not current_mem.percent.at("used").empty())) return current_mem; auto& show_swap = Config::getB("show_swap"); auto& swap_disk = Config::getB("swap_disk"); auto& show_disks = Config::getB("show_disks"); + auto totalMem = get_totalMem(); auto& mem = current_mem; - static const bool snapped = (getenv("BTOP_SNAPPED") != NULL); mem.stats.at("swap_total") = 0; @@ -714,7 +720,7 @@ namespace Mem { meminfo.ignore(SSmax, '\n'); } if (not got_avail) mem.stats.at("available") = mem.stats.at("free") + mem.stats.at("cached"); - mem.stats.at("used") = Shared::totalMem - mem.stats.at("available"); + mem.stats.at("used") = totalMem - mem.stats.at("available"); if (mem.stats.at("swap_total") > 0) mem.stats.at("swap_used") = mem.stats.at("swap_total") - mem.stats.at("swap_free"); } else @@ -724,7 +730,7 @@ namespace Mem { //? Calculate percentages 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 / totalMem)); while (cmp_greater(mem.percent.at(name).size(), width * 2)) mem.percent.at(name).pop_front(); } @@ -784,8 +790,12 @@ namespace Mem { for (string instr; diskread >> instr;) { if (not instr.starts_with('#')) { diskread >> instr; - if (snapped and instr == "/") fstab.push_back("/mnt"); - else if (not is_in(instr, "none", "swap")) fstab.push_back(instr); + #ifdef SNAPPED + if (instr == "/") fstab.push_back("/mnt"); + else if (not is_in(instr, "none", "swap")) fstab.push_back(instr); + #else + if (not is_in(instr, "none", "swap")) fstab.push_back(instr); + #endif } diskread.ignore(SSmax, '\n'); } @@ -822,7 +832,10 @@ namespace Mem { if (not disks.contains(mountpoint)) { disks[mountpoint] = disk_info{fs::canonical(dev, ec), fs::path(mountpoint).filename()}; if (disks.at(mountpoint).dev.empty()) disks.at(mountpoint).dev = dev; - if (disks.at(mountpoint).name.empty()) disks.at(mountpoint).name = (mountpoint == "/" or (snapped and mountpoint == "/mnt") ? "root" : mountpoint); + #ifdef SNAPPED + if (mountpoint == "/mnt") disks.at(mountpoint).name = "root"; + #endif + if (disks.at(mountpoint).name.empty()) disks.at(mountpoint).name = (mountpoint == "/" ? "root" : mountpoint); string devname = disks.at(mountpoint).dev.filename(); while (devname.size() >= 2) { if (fs::exists("/sys/block/" + devname + "/stat", ec) and access(string("/sys/block/" + devname + "/stat").c_str(), R_OK) == 0) { @@ -868,8 +881,11 @@ namespace Mem { //? Setup disks order in UI and add swap if enabled mem.disks_order.clear(); - if (snapped and disks.contains("/mnt")) mem.disks_order.push_back("/mnt"); - else if (disks.contains("/")) mem.disks_order.push_back("/"); + #ifdef SNAPPED + if (disks.contains("/mnt")) mem.disks_order.push_back("/mnt"); + #else + if (disks.contains("/")) mem.disks_order.push_back("/"); + #endif if (swap_disk and has_swap) { mem.disks_order.push_back("swap"); if (not disks.contains("swap")) disks["swap"] = {"", "swap"}; @@ -1259,7 +1275,7 @@ namespace Proc { detailed.memory = floating_humanizer(detailed.entry.mem); } if (detailed.first_mem == -1 or detailed.first_mem < detailed.mem_bytes.back() / 2 or detailed.first_mem > detailed.mem_bytes.back() * 4) { - detailed.first_mem = min((uint64_t)detailed.mem_bytes.back() * 2, Shared::totalMem); + detailed.first_mem = min((uint64_t)detailed.mem_bytes.back() * 2, Mem::get_totalMem()); redraw = true; } @@ -1324,6 +1340,9 @@ namespace Proc { else { should_filter = true; + auto totalMem = Mem::get_totalMem(); + int totalMem_len = to_string(totalMem >> 10).size(); + //? Update uid_user map if /etc/passwd changed since last run if (not Shared::passwd_path.empty() and fs::last_write_time(Shared::passwd_path) != passwd_time) { string r_uid, r_user; @@ -1410,7 +1429,26 @@ namespace Proc { } } pread.close(); - new_proc.user = (uid_user.contains(uid)) ? uid_user.at(uid) : uid; + if (uid_user.contains(uid)) { + new_proc.user = uid_user.at(uid); + } + else { + #ifndef STATIC_BUILD + try { + struct passwd* udet; + udet = getpwuid(stoi(uid)); + if (udet != NULL and udet->pw_name != NULL) { + new_proc.user = string(udet->pw_name); + } + else { + new_proc.user = uid; + } + } + catch (...) { new_proc.user = uid; } + #else + new_proc.user = uid; + #endif + } } //? Parse /proc/[pid]/stat @@ -1460,8 +1498,8 @@ namespace Proc { next_x = 24; continue; case 24: //? RSS memory (can be inaccurate, but parsing smaps increases total cpu usage by ~20x) - if (cmp_greater(short_str.size(), Shared::totalMem_len)) - new_proc.mem = Shared::totalMem; + if (cmp_greater(short_str.size(), totalMem_len)) + new_proc.mem = totalMem; else new_proc.mem = stoull(short_str) * Shared::pageSize; } @@ -1477,7 +1515,7 @@ namespace Proc { if (x-offset < 24) continue; //? Get RSS memory from /proc/[pid]/statm if value from /proc/[pid]/stat looks wrong - if (new_proc.mem >= Shared::totalMem) { + if (new_proc.mem >= totalMem) { pread.open(d.path() / "statm"); if (not pread.good()) continue; pread.ignore(SSmax, ' '); diff --git a/src/osx/btop_collect.cpp b/src/osx/btop_collect.cpp index e9eab43..749aa9c 100644 --- a/src/osx/btop_collect.cpp +++ b/src/osx/btop_collect.cpp @@ -360,9 +360,11 @@ namespace Cpu { } } } + CFRelease(one_ps_descriptor); + } else { + has_battery = false; } CFRelease(ps_info); - CFRelease(one_ps_descriptor); } return {percent, seconds, status}; } @@ -381,7 +383,6 @@ namespace Cpu { cpu.load_avg[0] = avg[0]; cpu.load_avg[1] = avg[1]; cpu.load_avg[2] = avg[2]; - natural_t cpu_count; natural_t i; processor_info_array_t info_array; |