Fix interactive job in background busy wait bug, reported by Randall D. Wald

darcs-hash:20090301021441-ac50b-a9488a9e55f545c3b8bd52aa0fb00b2b967974a8.gz
This commit is contained in:
axel 2009-03-01 12:14:41 +10:00
parent e0c317dfd4
commit 810d5f9548

View File

@ -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<block_count; i++ )
{
signal_block();
}
}
/* Put ourselves in our own process group. */
shell_pgid = getpid ();