diff --git a/include/util/command.hpp b/include/util/command.hpp index c9f238c1..fe0543d2 100644 --- a/include/util/command.hpp +++ b/include/util/command.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #ifdef __linux__ #include @@ -68,7 +69,11 @@ inline int close(FILE* fp, pid_t pid) { inline FILE* open(const std::string& cmd, int& pid) { if (cmd == "") return nullptr; int fd[2]; - if (pipe(fd) != 0) { + // Open the pipe with the close-on-exec flag set, so it will not be inherited + // by any other subprocesses launched by other threads (which could result in + // the pipe staying open after this child dies, causing us to hang when trying + // to read from it) + if (pipe2(fd, O_CLOEXEC) != 0) { spdlog::error("Unable to pipe fd"); return nullptr; } @@ -77,6 +82,8 @@ inline FILE* open(const std::string& cmd, int& pid) { if (child_pid < 0) { spdlog::error("Unable to exec cmd {}, error {}", cmd.c_str(), strerror(errno)); + ::close(fd[0]); + ::close(fd[1]); return nullptr; } diff --git a/src/modules/network.cpp b/src/modules/network.cpp index a61edd5c..ef8b2bd4 100644 --- a/src/modules/network.cpp +++ b/src/modules/network.cpp @@ -188,7 +188,7 @@ void waybar::modules::Network::createEventSocket() { throw std::runtime_error("Can't create epoll"); } { - ev_fd_ = eventfd(0, EFD_NONBLOCK); + ev_fd_ = eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC); struct epoll_event event; memset(&event, 0, sizeof(event)); event.events = EPOLLIN | EPOLLET;