diff --git a/include/util/command.hpp b/include/util/command.hpp index a72a8294..9db8d833 100644 --- a/include/util/command.hpp +++ b/include/util/command.hpp @@ -7,6 +7,9 @@ #include +extern sig_atomic_t is_inserting_pid; +extern std::list reap; + namespace waybar::util::command { struct res { @@ -32,10 +35,11 @@ inline std::string read(FILE* fp) { inline int close(FILE* fp, pid_t pid) { int stat = -1; + pid_t ret; fclose(fp); do { - waitpid(pid, &stat, WCONTINUED | WUNTRACED); + ret = waitpid(pid, &stat, WCONTINUED | WUNTRACED); if (WIFEXITED(stat)) { spdlog::debug("Cmd exited with code {}", WEXITSTATUS(stat)); @@ -45,6 +49,8 @@ inline int close(FILE* fp, pid_t pid) { spdlog::debug("Cmd stopped by {}", WSTOPSIG(stat)); } else if (WIFCONTINUED(stat)) { spdlog::debug("Cmd continued"); + } else if (ret == -1) { + spdlog::debug("waitpid failed: {}", strerror(errno)); } else { break; } @@ -111,7 +117,9 @@ inline int32_t forkExec(const std::string& cmd) { execl("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0); exit(0); } else { - signal(SIGCHLD, SIG_IGN); + is_inserting_pid = true; + reap.push_back(pid); + is_inserting_pid = false; } return pid; diff --git a/src/main.cpp b/src/main.cpp index f066cf85..5350ec09 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,32 @@ #include +#include +#include +#include #include #include "client.hpp" +sig_atomic_t is_inserting_pid = false; +std::list reap; + +static void handler(int sig) { + int saved_errno = errno; + if (!is_inserting_pid) { + for (auto it = reap.begin(); it != reap.end(); ++it) { + if (waitpid(*it, nullptr, WNOHANG) == *it) { + it = reap.erase(it); + } + } + } + errno = saved_errno; +} + +inline void installSigChldHandler(void) { + struct sigaction sa; + sigemptyset(&sa.sa_mask); + sa.sa_handler = handler; + sigaction(SIGCHLD, &sa, nullptr); +} + int main(int argc, char* argv[]) { try { auto client = waybar::Client::inst(); @@ -18,6 +43,7 @@ int main(int argc, char* argv[]) { } }); } + installSigChldHandler(); auto ret = client->main(argc, argv); delete client;