From 810d5f9548301b0f7297abf68d7a272724250fc8 Mon Sep 17 00:00:00 2001 From: axel Date: Sun, 1 Mar 2009 12:14:41 +1000 Subject: [PATCH] Fix interactive job in background busy wait bug, reported by Randall D. Wald darcs-hash:20090301021441-ac50b-a9488a9e55f545c3b8bd52aa0fb00b2b967974a8.gz --- reader.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/reader.c b/reader.c index f47a417..23b5d9d 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