core: move to Hyprutils::OS::CProcess for spawning processes (#575)

* core: move to Hyprutils::OS::CProcess for spawning processes

* nix: flake update
This commit is contained in:
Maximilian Seidler 2024-12-08 15:42:16 +00:00 committed by GitHub
parent cc7ffe73e7
commit 8010b81e7b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 27 additions and 82 deletions

View file

@ -56,7 +56,7 @@ pkg_check_modules(
pangocairo pangocairo
libdrm libdrm
gbm gbm
hyprutils>=0.2.3 hyprutils>=0.2.6
sdbus-c++>=2.0.0 sdbus-c++>=2.0.0
hyprgraphics) hyprgraphics)

View file

@ -13,11 +13,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1732808127, "lastModified": 1733248371,
"narHash": "sha256-jwqYmLVfvoLPu8UScEzZgdbbiNU3ioYcrsthjEEnGqI=", "narHash": "sha256-FFLJzFTyNhS7tBEEECx0B8Ye/bpmxhFVEKlECgMLc6c=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprgraphics", "repo": "hyprgraphics",
"rev": "4d927a52be7e15e0846456f2aa1b0ad76b5bf059", "rev": "cc95e5babc6065bc3ab4cd195429a9900836ef13",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -62,11 +62,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1727300645, "lastModified": 1733502241,
"narHash": "sha256-OvAtVLaSRPnbXzOwlR1fVqCXR7i+ICRX3aPMCdIiv+c=", "narHash": "sha256-KAUNC4Dgq8WQjYov5auBw/usaHixhacvb7cRDd0AG/k=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprutils", "repo": "hyprutils",
"rev": "3f5293432b6dc6a99f26aca2eba3876d2660665c", "rev": "104117aed6dd68561be38b50f218190aa47f2cd8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -77,11 +77,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1728492678, "lastModified": 1733392399,
"narHash": "sha256-9UTxR8eukdg+XZeHgxW5hQA9fIKHsKCdOIUycTryeVw=", "narHash": "sha256-kEsTJTUQfQFIJOcLYFt/RvNxIK653ZkTBIs4DG+cBns=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "5633bcff0c6162b9e4b5f1264264611e950c8ec7", "rev": "d0797a04b81caeae77bcff10a9dde78bc17f5661",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -19,6 +19,9 @@
#include <fstream> #include <fstream>
#include <algorithm> #include <algorithm>
#include <sdbus-c++/sdbus-c++.h> #include <sdbus-c++/sdbus-c++.h>
#include <hyprutils/os/Process.hpp>
using namespace Hyprutils::OS;
CHyprlock::CHyprlock(const std::string& wlDisplay, const bool immediate, const bool immediateRender, const bool noFadeIn) { CHyprlock::CHyprlock(const std::string& wlDisplay, const bool immediate, const bool immediateRender, const bool noFadeIn) {
m_sWaylandState.display = wl_display_connect(wlDisplay.empty() ? nullptr : wlDisplay.c_str()); m_sWaylandState.display = wl_display_connect(wlDisplay.empty() ? nullptr : wlDisplay.c_str());
@ -1105,74 +1108,17 @@ void CHyprlock::enqueueForceUpdateTimers() {
addTimer(std::chrono::milliseconds(1), [](std::shared_ptr<CTimer> self, void* data) { forceUpdateTimers(); }, nullptr, false); addTimer(std::chrono::milliseconds(1), [](std::shared_ptr<CTimer> self, void* data) { forceUpdateTimers(); }, nullptr, false);
} }
void CHyprlock::spawnAsync(const std::string& args) {
Debug::log(LOG, "Executing (async) {}", args);
int socket[2];
if (pipe(socket) != 0)
Debug::log(LOG, "Unable to create pipe for fork");
pid_t child, grandchild;
child = fork();
if (child < 0) {
close(socket[0]);
close(socket[1]);
Debug::log(LOG, "Fail to create the first fork");
return;
}
if (child == 0) {
// run in child
sigset_t set;
sigemptyset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
grandchild = fork();
if (grandchild == 0) {
// run in grandchild
close(socket[0]);
close(socket[1]);
execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr);
// exit grandchild
_exit(0);
}
close(socket[0]);
write(socket[1], &grandchild, sizeof(grandchild));
close(socket[1]);
// exit child
_exit(0);
}
// run in parent
close(socket[1]);
read(socket[0], &grandchild, sizeof(grandchild));
close(socket[0]);
// clear child and leave child to init
waitpid(child, NULL, 0);
if (child < 0) {
Debug::log(LOG, "Failed to create the second fork");
return;
}
Debug::log(LOG, "Process Created with pid {}", grandchild);
}
std::string CHyprlock::spawnSync(const std::string& cmd) { std::string CHyprlock::spawnSync(const std::string& cmd) {
std::array<char, 128> buffer; CProcess proc("/bin/sh", {"-c", cmd});
std::string result; if (!proc.runSync()) {
const std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose); Debug::log(ERR, "Failed to run \"{}\"", cmd);
if (!pipe)
return ""; return "";
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
} }
return result;
if (!proc.stdErr().empty())
Debug::log(ERR, "Shell command \"{}\" STDERR:\n{}", cmd, proc.stdErr());
return proc.stdOut();
} }
zwlr_screencopy_manager_v1* CHyprlock::getScreencopy() { zwlr_screencopy_manager_v1* CHyprlock::getScreencopy() {

View file

@ -52,7 +52,6 @@ class CHyprlock {
void attemptRestoreOnDeath(); void attemptRestoreOnDeath();
void spawnAsync(const std::string& cmd);
std::string spawnSync(const std::string& cmd); std::string spawnSync(const std::string& cmd);
void onKey(uint32_t key, bool down); void onKey(uint32_t key, bool down);

View file

@ -221,11 +221,11 @@ void CAsyncResourceGatherer::renderText(const SPreloadRequest& rq) {
const bool ISCMD = rq.props.contains("cmd") ? std::any_cast<bool>(rq.props.at("cmd")) : false; const bool ISCMD = rq.props.contains("cmd") ? std::any_cast<bool>(rq.props.at("cmd")) : false;
static auto* const TRIM = (Hyprlang::INT* const*)g_pConfigManager->getValuePtr("general:text_trim"); static auto* const TRIM = (Hyprlang::INT* const*)g_pConfigManager->getValuePtr("general:text_trim");
std::string TEXT = ISCMD ? g_pHyprlock->spawnSync(rq.asset) : rq.asset; std::string text = ISCMD ? g_pHyprlock->spawnSync(rq.asset) : rq.asset;
if (**TRIM) { if (**TRIM) {
TEXT.erase(0, TEXT.find_first_not_of(" \n\r\t")); text.erase(0, text.find_first_not_of(" \n\r\t"));
TEXT.erase(TEXT.find_last_not_of(" \n\r\t") + 1); text.erase(text.find_last_not_of(" \n\r\t") + 1);
} }
auto CAIROSURFACE = makeShared<CCairoSurface>(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1920, 1080 /* dummy value */)); auto CAIROSURFACE = makeShared<CCairoSurface>(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1920, 1080 /* dummy value */));
@ -253,12 +253,12 @@ void CAsyncResourceGatherer::renderText(const SPreloadRequest& rq) {
PangoAttrList* attrList = nullptr; PangoAttrList* attrList = nullptr;
GError* gError = nullptr; GError* gError = nullptr;
char* buf = nullptr; char* buf = nullptr;
if (pango_parse_markup(TEXT.c_str(), -1, 0, &attrList, &buf, nullptr, &gError)) if (pango_parse_markup(text.c_str(), -1, 0, &attrList, &buf, nullptr, &gError))
pango_layout_set_text(layout, buf, -1); pango_layout_set_text(layout, buf, -1);
else { else {
Debug::log(ERR, "Pango markup parsing for {} failed: {}", TEXT, gError->message); Debug::log(ERR, "Pango markup parsing for {} failed: {}", text, gError->message);
g_error_free(gError); g_error_free(gError);
pango_layout_set_text(layout, TEXT.c_str(), -1); pango_layout_set_text(layout, text.c_str(), -1);
} }
if (!attrList) if (!attrList)