Will Thompson authored
Previously, we sent SIGKILL directly to the child process. If we're monitoring the system bus, the child process is owned by root, so the parent process can't send it signals. In this case, we relied on the child process dying with "Broken pipe" when it next tries to write to stdout (which we close). If you run `pkexec dbus-monitor --system` in a terminal, you are able to press Ctrl-C to send SIGINT to that privileged child process. This is because the signal is not sent directly. Instead, the terminal emulator writes ^C to the child's controlling terminal; the kernel turns this into SIGINT and send that to the child. We can do the same thing here. Here are the steps: * Create a pseudo-terminal (PTY) master/slave (not my terminology) pair * Make this PTY the controlling terminal for the child process: * Make the slave FD the stdin for the child * In a GSubprocessLauncher child_setup function, which runs between fork() and exec(): * Move the process to a new session with setsid(), removing any existing controlling terminal * Call ioctl(STDIN_FILENO, TIOCSCTTY, 0) to set the stdin FD as the controlling terminal * When it comes time to kill the child, write ^C into the master side of the PTY We continue to send SIGINT (rather than SIGKILL; it seems kinder) the old-fashioned way (in case something goes wrong setting the controlling terminal) and closing the pipe so that the child eventually dies with EPIPE (in case the old-fashioned way fails too). A potential fly in the works is that, in the Flatpak case, the immediate child is a flatpak-spawn process; `pkexec dbus-monitor --system` is actually launched from the session helper. Happily, the session helper already calls setsid() + TIOCSCTTY if any of stdin/stdout/stderr on the spawned process are TTYs <https://github.com/flatpak/flatpak/blob/1.0.1/session-helper/flatpak-session-helper.c#L182-L202> so we just skip the child_setup function in that case. See https://blog.nelhage.com/2011/02/changing-ctty/ for some useful background reading on controlling terminals.