[common] open: detach xdg-open instead of waiting for it

Sometimes, e.g. when xdg-open has to start the browser, the xdg-open
process can stay around until the browser exits, which freezes the
client. Instead, we should not wait for xdg-open to exit.

However, we can't simply not call wait, as that would leave the
xdg-open process around as a zombie. We could turn off the SIGCHLD
handler, but that's a global solution to a local problem. Instead, we
call setsid and fork again to detach the xdg-open process as if it's a
daemon, and let init take care of the reaping process.

Co-Authored-By: Tudor Brindus <me@tbrindus.ca>
This commit is contained in:
Quantum 2021-09-23 23:07:15 -04:00 committed by Geoffrey McRae
parent bc65de5987
commit 57d220a43b

View File

@ -31,8 +31,15 @@ static bool xdgOpen(const char * path)
pid_t pid = fork(); pid_t pid = fork();
if (pid == 0) if (pid == 0)
{ {
execlp("xdg-open", "xdg-open", path, NULL); // setsid and fork again to detach the xdg-open process.
_exit(127); setsid();
pid_t pid = fork();
if (pid == 0)
{
execlp("xdg-open", "xdg-open", path, NULL);
_exit(127);
}
_exit(pid < 0);
} }
else if (pid < 0) else if (pid < 0)
{ {
@ -52,9 +59,9 @@ static bool xdgOpen(const char * path)
return true; return true;
if (WIFEXITED(status)) if (WIFEXITED(status))
DEBUG_ERROR("xdg-open exited with code %d", WEXITSTATUS(status)); DEBUG_ERROR("helper process exited with code %d", WEXITSTATUS(status));
else else
DEBUG_ERROR("xdg-open exited with signal: %s", strsignal(WTERMSIG(status))); DEBUG_ERROR("helper process exited with signal: %s", strsignal(WTERMSIG(status)));
return false; return false;
} }
} }