From 3f1d7bbdc5e300bd1b6cbd93901ec4aa5578bc0b Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Fri, 28 Jun 2019 11:48:33 -0700 Subject: [PATCH] Call tcsetpgrp in child processes before resetting signal handlers Also ignore SIGTTIN and SIGTTOU across the tcsetpgrp call. Hopeful fix for #5963 --- src/postfork.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/postfork.cpp b/src/postfork.cpp index e0e18acd0..5508ae215 100644 --- a/src/postfork.cpp +++ b/src/postfork.cpp @@ -165,19 +165,21 @@ int child_setup_process(const job_t *job, process_t *p, const dup2_list_t &dup2s return err; } } - // Set the handling for job control signals back to the default. - signal_reset_handlers(); - if (job != nullptr && job->wants_terminal() && job->is_foreground()) { // Assign the terminal within the child to avoid the well-known race between tcsetgrp() in // the parent and the child executing. We are not interested in error handling here, except // we try to avoid this for non-terminals; in particular pipelines often make non-terminal // stdin. if (isatty(STDIN_FILENO)) { + // Ensure this doesn't send us to the background (see #5963) + signal(SIGTTIN, SIG_IGN); + signal(SIGTTOU, SIG_IGN); (void)tcsetpgrp(STDIN_FILENO, job->pgid); } } - + // Set the handling for job control signals back to the default. + // Do this after any tcsetpgrp call so that we swallow SIGTTIN. + signal_reset_handlers(); return 0; }