Factor out some of the crazy logic in reader_interactive_init

This commit is contained in:
ridiculousfish 2020-01-31 11:11:03 -08:00
parent 8d8bcb7d8a
commit 1101cff566

View File

@ -1683,19 +1683,18 @@ static bool check_for_orphaned_process(unsigned long loop_count, pid_t shell_pgi
return we_think_we_are_orphaned; return we_think_we_are_orphaned;
} }
/// Initialize data for interactive use. // Ensure that fish owns the terminal, possibly waiting. If we cannot acquire the terminal, then
static void reader_interactive_init(parser_t &parser) { // report an error and exit.
// See if we are running interactively. static void acquire_tty_or_exit(pid_t shell_pgid) {
pid_t shell_pgid; ASSERT_IS_MAIN_THREAD();
init_input();
shell_pgid = getpgrp();
// This should enable job control on fish, even if our parent process did not enable it for us.
// Check if we are in control of the terminal, so that we don't do semi-expensive things like // Check if we are in control of the terminal, so that we don't do semi-expensive things like
// reset signal handlers unless we really have to, which we often don't. // reset signal handlers unless we really have to, which we often don't.
if (tcgetpgrp(STDIN_FILENO) != shell_pgid) { // Common case.
if (tcgetpgrp(STDIN_FILENO) == shell_pgid) {
return;
}
// Bummer, we are not in control of the terminal. Stop until parent has given us control of // Bummer, we are not in control of the terminal. Stop until parent has given us control of
// it. // it.
// //
@ -1703,6 +1702,7 @@ static void reader_interactive_init(parser_t &parser) {
// practice, this code should only be run during startup, when we're not waiting for any // practice, this code should only be run during startup, when we're not waiting for any
// signals. // signals.
signal_reset_handlers(); signal_reset_handlers();
cleanup_t restore_sigs([] { signal_set_handlers(true); });
// Ok, signal handlers are taken out of the picture. Stop ourself in a loop until we are in // Ok, signal handlers are taken out of the picture. Stop ourself in a loop until we are in
// control of the terminal. However, the call to signal(SIGTTIN) may silently not do // control of the terminal. However, the call to signal(SIGTTIN) may silently not do
@ -1713,7 +1713,7 @@ static void reader_interactive_init(parser_t &parser) {
// possibility is that read() from the tty fails with EIO - this is more reliable but it's // possibility is that read() from the tty fails with EIO - this is more reliable but it's
// harder, because it may succeed or block. So we loop for a while, trying those strategies. // harder, because it may succeed or block. So we loop for a while, trying those strategies.
// Eventually we just give up and assume we're orphaend. // Eventually we just give up and assume we're orphaend.
for (unsigned long loop_count = 0;; loop_count++) { for (unsigned loop_count = 0;; loop_count++) {
pid_t owner = tcgetpgrp(STDIN_FILENO); pid_t owner = tcgetpgrp(STDIN_FILENO);
// 0 is a valid return code from `tcgetpgrp()` under at least FreeBSD and testing // 0 is a valid return code from `tcgetpgrp()` under at least FreeBSD and testing
// indicates that a subsequent call to `tcsetpgrp()` will succeed. 0 is the // indicates that a subsequent call to `tcsetpgrp()` will succeed. 0 is the
@ -1758,10 +1758,23 @@ static void reader_interactive_init(parser_t &parser) {
} }
} }
} }
signal_set_handlers(parser.is_interactive());
} }
/// Initialize data for interactive use.
static void reader_interactive_init(parser_t &parser) {
ASSERT_IS_MAIN_THREAD();
pid_t shell_pgid = getpgrp();
// Set up key bindings.
init_input();
// Ensure interactive signal handling is enabled.
signal_set_handlers_once(true);
// Wait until we own the terminal.
acquire_tty_or_exit(shell_pgid);
// It shouldn't be necessary to place fish in its own process group and force control // It shouldn't be necessary to place fish in its own process group and force control
// of the terminal, but that works around fish being started with an invalid pgroup, // of the terminal, but that works around fish being started with an invalid pgroup,
// such as when launched via firejail (#5295) // such as when launched via firejail (#5295)