diff options
author | Thomas Voss <[email protected]> | 2022-11-13 12:58:20 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2022-11-13 11:58:20 +0000 |
commit | 1e5cab1ee7a82d3381f55963a0ff768c30215602 (patch) | |
tree | 28f84bdd95fd01ef9dc5bd403c610126e15432a5 | |
parent | 5a00f0c657fbfca0ab4fbd5f388042d6084a5997 (diff) | |
download | Hyprland-1e5cab1ee7a82d3381f55963a0ff768c30215602.tar.gz Hyprland-1e5cab1ee7a82d3381f55963a0ff768c30215602.zip |
Set child stdout and stderr to /dev/null (#1000)
Some scripts or utilities check to see if stdout or stderr are connected
to a TTY or not to determine certain behaviors (for example, you might
want to prompt a user for input with fzf(1) if in a terminal but tofi(1)
or wofi(1) when spawned from your WM). Since hyprland never closes
these output streams for spawned processes, they end up just spewing
their output onto the TTY while giving the user no real way to have a
script detect if it's being run from the shell or WM.
Instead of just closing stdout and stderr though, we close them and then
proceed to reopen them but connect them to /dev/null. This allows
scripts and processes to not fail when attempting to write, but for that
writing to simply have no effect.
-rw-r--r-- | src/managers/KeybindManager.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index a529da97..86248861 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1,5 +1,7 @@ #include "KeybindManager.hpp" +#include <fcntl.h> +#include <paths.h> #include <regex> CKeybindManager::CKeybindManager() { @@ -526,6 +528,25 @@ void CKeybindManager::spawn(std::string args) { // run in grandchild close(socket[0]); close(socket[1]); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + int devnull = open(_PATH_DEVNULL, O_WRONLY); + if (devnull == -1) { + Debug::log(LOG, "Unable to open /dev/null for writing"); + return; + } + + if (dup2(devnull, STDOUT_FILENO) == -1) { + Debug::log(LOG, "Unable to duplicate /dev/null to stdout"); + return; + } + if (dup2(devnull, STDERR_FILENO) == -1) { + Debug::log(LOG, "Unable to duplicate /dev/null to stderr"); + return; + } + + close(devnull); execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr); // exit grandchild _exit(0); |