Prevent child zombie process from tearing down Hyprland IPC

In rare circumstances, we may fork(), e.g., as part of a custom module,
and the child process may fail to exec() and exit. In those cases, the
IPC destructor will be called in the child process.

Prior to this commit, this call would then result in the shared socket
being closed. Prevent this by only closing the socket from the original
process.

Fixes #3975 and #4152.

Signed-off-by: Lukas Fleischer <lfleischer@lfos.de>
This commit is contained in:
Lukas Fleischer
2025-08-22 18:44:20 -04:00
parent 41de8964f1
commit 5a29473080
2 changed files with 6 additions and 0 deletions

View File

@ -42,6 +42,7 @@ class IPC {
util::JsonParser parser_; util::JsonParser parser_;
std::list<std::pair<std::string, EventHandler*>> callbacks_; std::list<std::pair<std::string, EventHandler*>> callbacks_;
int socketfd_; // the hyprland socket file descriptor int socketfd_; // the hyprland socket file descriptor
pid_t socketOwnerPid_;
bool running_ = true; bool running_ = true;
}; };

View File

@ -46,9 +46,14 @@ std::filesystem::path IPC::getSocketFolder(const char* instanceSig) {
IPC::IPC() { IPC::IPC() {
// will start IPC and relay events to parseIPC // will start IPC and relay events to parseIPC
ipcThread_ = std::thread([this]() { socketListener(); }); ipcThread_ = std::thread([this]() { socketListener(); });
socketOwnerPid_ = getpid();
} }
IPC::~IPC() { IPC::~IPC() {
// Do no stop Hyprland IPC if a child process (with successful fork() but
// failed exec()) exits.
if (getpid() != socketOwnerPid_) return;
running_ = false; running_ = false;
spdlog::info("Hyprland IPC stopping..."); spdlog::info("Hyprland IPC stopping...");
if (socketfd_ != -1) { if (socketfd_ != -1) {