diff options
| author | s1dd <140317709+nots1dd@users.noreply.github.com> | 2025-05-05 07:52:22 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-05 04:22:22 +0200 |
| commit | 1c530cbc66dbff585d55e435efd5e6a6e5614f88 (patch) | |
| tree | e13ff1a4548f8fbcc29774480b9fb1091e37e459 /hyprpm/src/helpers/Sys.cpp | |
| parent | 9cd5b257459a6b4c5d5d4d1026df85f0ecbe5a93 (diff) | |
hyprpm: Minor optimizations and refactor of helpers and progress bar (#10246)
* hyprpm: optimize sys.cpp
* hyprpm: refine progress bar logic
* chore: fix fetchSuperuserBins
* chore: modify one line if/else statements
* chore: fix if/else statements
* chore: follow naming convention for const vars
* chore: revert shell escape logic
Diffstat (limited to 'hyprpm/src/helpers/Sys.cpp')
| -rw-r--r-- | hyprpm/src/helpers/Sys.cpp | 84 |
1 files changed, 48 insertions, 36 deletions
diff --git a/hyprpm/src/helpers/Sys.cpp b/hyprpm/src/helpers/Sys.cpp index 3c6501ee..8a6bb687 100644 --- a/hyprpm/src/helpers/Sys.cpp +++ b/hyprpm/src/helpers/Sys.cpp @@ -1,59 +1,72 @@ #include "Sys.hpp" #include "Die.hpp" #include "StringUtils.hpp" + #include <pwd.h> #include <unistd.h> #include <print> #include <filesystem> +#include <optional> #include <hyprutils/os/Process.hpp> #include <hyprutils/string/VarList.hpp> + using namespace Hyprutils::OS; using namespace Hyprutils::String; -static const std::vector<const char*> SUPERUSER_BINARIES = { +inline constexpr std::array<std::string_view, 3> SUPERUSER_BINARIES = { "sudo", "doas", "run0", }; +static std::string fetchSuperuserBins() { + std::ostringstream oss; + auto it = SUPERUSER_BINARIES.begin(); + if (it != SUPERUSER_BINARIES.end()) { + oss << *it++; + for (; it != SUPERUSER_BINARIES.end(); ++it) + oss << ", " << *it; + } + + return oss.str(); +} + static bool executableExistsInPath(const std::string& exe) { - if (!getenv("PATH")) + const char* PATHENV = std::getenv("PATH"); + if (!PATHENV) return false; - static CVarList paths(getenv("PATH"), 0, ':', true); + CVarList paths(PATHENV, 0, ':', true); + std::error_code ec; - for (auto& p : paths) { - std::string path = p + std::string{"/"} + exe; - std::error_code ec; - if (!std::filesystem::exists(path, ec) || ec) + for (const auto& PATH : paths) { + std::filesystem::path candidate = std::filesystem::path(PATH) / exe; + if (!std::filesystem::exists(candidate, ec) || ec) continue; - - if (!std::filesystem::is_regular_file(path, ec) || ec) + if (!std::filesystem::is_regular_file(candidate, ec) || ec) continue; - - auto stat = std::filesystem::status(path, ec); + auto perms = std::filesystem::status(candidate, ec).permissions(); if (ec) continue; - - auto perms = stat.permissions(); - - return std::filesystem::perms::none != (perms & std::filesystem::perms::others_exec); + if ((perms & std::filesystem::perms::others_exec) != std::filesystem::perms::none) + return true; } return false; } -static std::pair<std::string, int> execAndGet(std::string cmd, bool noRedirect = false) { +static std::optional<std::pair<std::string, int>> execAndGet(std::string_view cmd, bool noRedirect = false) { + std::string command = std::string{cmd}; if (!noRedirect) - cmd += " 2>&1"; - - CProcess proc("/bin/sh", {"-c", cmd}); + command += " 2>&1"; + CProcess proc("/bin/sh", {"-c", command}); if (!proc.runSync()) - return {"error", 1}; + // optional handles nullopt gracefully + return std::nullopt; - return {proc.stdOut(), proc.exitCode()}; + return {{proc.stdOut(), proc.exitCode()}}; } int NSys::getUID() { @@ -69,23 +82,22 @@ int NSys::getEUID() { } bool NSys::isSuperuser() { - return getuid() != geteuid() || !geteuid(); + return getuid() != geteuid() || geteuid() == 0; } std::string NSys::runAsSuperuser(const std::string& cmd) { - for (const auto& SB : SUPERUSER_BINARIES) { - if (!executableExistsInPath(SB)) + for (const auto& BIN : SUPERUSER_BINARIES) { + if (!executableExistsInPath(std::string{BIN})) continue; - const auto RESULT = execAndGet(std::string{SB} + " /bin/sh -c \"" + cmd + "\"", true); - - if (RESULT.second != 0) + const auto result = execAndGet(std::string{BIN} + " /bin/sh -c " + cmd, true); + if (!result.has_value() || result->second != 0) Debug::die("Failed to run a command as sudo. This could be due to an invalid password, or a hyprpm bug."); - return RESULT.first; + return result->first; } - Debug::die("Failed to find a superuser binary. Supported: sudo, doas, run0."); + Debug::die("{} {}", "Failed to find a superuser binary. Supported: ", fetchSuperuserBins()); return ""; } @@ -96,15 +108,15 @@ void NSys::cacheSudo() { } void NSys::dropSudo() { - for (const auto& SB : SUPERUSER_BINARIES) { - if (!executableExistsInPath(SB)) + for (const auto& BIN : SUPERUSER_BINARIES) { + if (!executableExistsInPath(std::string{BIN})) continue; - if (SB == std::string_view{"sudo"}) + if (BIN == "sudo") execAndGet("sudo -k"); - else - std::println("{}", infoString("Don't know how to drop timestamp for {}, ignoring.", SB)); - - return; + else { + // note the superuser binary that is being dropped + std::println("{}", infoString("Don't know how to drop timestamp for '{}', ignoring.", BIN)); + } } } |
