Skip to content

Commit

Permalink
core: move to Hyprutils::OS::CProcess for spawning processes (#575)
Browse files Browse the repository at this point in the history
* core: move to Hyprutils::OS::CProcess for spawning processes

* nix: flake update
  • Loading branch information
PaideiaDilemma authored Dec 8, 2024
1 parent cc7ffe7 commit 8010b81
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 82 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pkg_check_modules(
pangocairo
libdrm
gbm
hyprutils>=0.2.3
hyprutils>=0.2.6
sdbus-c++>=2.0.0
hyprgraphics)

Expand Down
18 changes: 9 additions & 9 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 11 additions & 65 deletions src/core/hyprlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#include <fstream>
#include <algorithm>
#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) {
m_sWaylandState.display = wl_display_connect(wlDisplay.empty() ? nullptr : wlDisplay.c_str());
Expand Down Expand Up @@ -1105,74 +1108,17 @@ void CHyprlock::enqueueForceUpdateTimers() {
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::array<char, 128> buffer;
std::string result;
const std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
if (!pipe)
CProcess proc("/bin/sh", {"-c", cmd});
if (!proc.runSync()) {
Debug::log(ERR, "Failed to run \"{}\"", cmd);
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() {
Expand Down
1 change: 0 additions & 1 deletion src/core/hyprlock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ class CHyprlock {

void attemptRestoreOnDeath();

void spawnAsync(const std::string& cmd);
std::string spawnSync(const std::string& cmd);

void onKey(uint32_t key, bool down);
Expand Down
12 changes: 6 additions & 6 deletions src/renderer/AsyncResourceGatherer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

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) {
TEXT.erase(0, TEXT.find_first_not_of(" \n\r\t"));
TEXT.erase(TEXT.find_last_not_of(" \n\r\t") + 1);
text.erase(0, text.find_first_not_of(" \n\r\t"));
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 */));
Expand Down Expand Up @@ -253,12 +253,12 @@ void CAsyncResourceGatherer::renderText(const SPreloadRequest& rq) {
PangoAttrList* attrList = nullptr;
GError* gError = 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);
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);
pango_layout_set_text(layout, TEXT.c_str(), -1);
pango_layout_set_text(layout, text.c_str(), -1);
}

if (!attrList)
Expand Down

0 comments on commit 8010b81

Please sign in to comment.