diff --git a/reader.c b/reader.c index f47a417ab..23b5d9d8e 100644 --- a/reader.c +++ b/reader.c @@ -1615,11 +1615,52 @@ static void reader_interactive_init() not enable it for us. */ - /* Loop until we are in the foreground. */ - while (tcgetpgrp( 0 ) != shell_pgid) + /* + 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. + */ + if (tcgetpgrp( 0 ) != shell_pgid) { - killpg( shell_pgid, SIGTTIN); + int block_count = 0; + int i; + + /* + Bummer, we are not in control of the terminal. Stop until + parent has given us control of it. Stopping in fish is a bit + of a challange, what with all the signal fidgeting, we need + to reset a bunch of signal state, making this coda a but + unobvious. + + In theory, reseting signal handlers could cause us to miss + signal deliveries. In practice, this code should only be run + suring startup, when we're not waiting for any signals. + */ + while (signal_is_blocked()) + { + signal_unblock(); + block_count++; + } + signal_reset_handlers(); + + /* + Ok, signal handlers are taken out of the picture. Stop ourself in a loop + until we are in control of the terminal. + */ + while (tcgetpgrp( 0 ) != shell_pgid) + { + killpg( shell_pgid, SIGTTIN); + } + + signal_set_handlers(); + + for( i=0; i