Change the foregrounf/background code a bit, fixes bug where mulktiple jobs want foreground status. Is this fix enough or are there still corner cases?

darcs-hash:20060118124248-ac50b-cbbddb8c6dad1f44826050395cda647fa9348f0f.gz
This commit is contained in:
axel 2006-01-18 22:42:48 +10:00
parent e15c7fd7e0
commit 05736978bb
7 changed files with 44 additions and 36 deletions

View file

@ -325,7 +325,6 @@ static void event_fire_internal( event_t *event )
array_list_t *fire=0;
int was_subshell = is_subshell;
// int was_interactive = is_interactive;
/*
First we free all events that have been removed
@ -402,7 +401,6 @@ static void event_fire_internal( event_t *event )
they are marked as non-interactive and as a subshell
*/
is_subshell=1;
// is_interactive=0;
eval( (wchar_t *)b->buff, 0, TOP );
}
@ -411,7 +409,6 @@ static void event_fire_internal( event_t *event )
Restore interactivity flags
*/
is_subshell = was_subshell;
// is_interactive = was_interactive;
if( b )
{
@ -531,7 +528,6 @@ void event_fire( event_t *event )
sig_list[active_list].signal[sig_list[active_list].count++]=event->param1.signal;
else
sig_list[active_list].overflow=1;
}
else
{

14
exec.c
View file

@ -392,8 +392,8 @@ static int handle_child_io( io_data_t *io, int exit_on_error )
static int setup_child_process( job_t *j, process_t *p )
{
int res;
if( is_interactive && p->type==EXTERNAL )
if( j->terminal )
{
pid_t pid;
/*
@ -442,6 +442,7 @@ static int setup_child_process( job_t *j, process_t *p )
*/
static void launch_process( process_t *p )
{
// debug( 1, L"exec '%ls'", p->argv[0] );
execve (wcs2str(p->actual_cmd), wcsv2strv( (const wchar_t **) p->argv), env_export_arr( 0 ) );
debug( 0,
@ -601,7 +602,7 @@ static void internal_exec_helper( const wchar_t *def,
static int handle_new_child( job_t *j, process_t *p )
{
if( is_interactive && p->type==EXTERNAL )
if( j->terminal )
{
int new_pgid=0;
@ -678,7 +679,7 @@ void exec( job_t *j )
int exec_error=0;
debug( 4, L"Exec job %ls with id %d", j->command, j->job_id );
debug( 4, L"Exec job '%ls' with id %d", j->command, j->job_id );
if( j->first_process->type==INTERNAL_EXEC )
{
@ -704,8 +705,7 @@ void exec( job_t *j )
return;
}
}
}
pipe_read.fd=0;
pipe_write.fd=1;
@ -1014,6 +1014,7 @@ void exec( job_t *j )
if( io_buffer->param2.out_buffer->used != 0 )
{
pid = fork();
if( pid == 0 )
{
/*
@ -1309,5 +1310,6 @@ int exec_subshell( const wchar_t *cmd,
}
io_buffer_destroy( io_buffer );
return status;
}

20
input.c
View file

@ -1292,12 +1292,32 @@ static int interrupt_handler()
Fire any pending events
*/
event_fire( 0 );
/*
Reap stray processes, including printing exit status messages
*/
if( job_reap( 1 ) )
repaint();
/*
Check if we should exit
*/
if( exit_status() )
{
return R_EXIT;
}
/*
Tell the reader an event occured
*/
if( reader_interupted() )
{
/*
Return 3, i.e. the character read by a Control-C.
*/
return 3;
}
return 0;
}

View file

@ -1162,6 +1162,7 @@ static void parse_job_main_loop( process_t *p,
case TOK_BACKGROUND:
j->fg = 0;
j->terminal=0;
case TOK_END:
{
p->argv = list_to_char_arr( args );
@ -1981,10 +1982,10 @@ static void eval_job( tokenizer *tok )
j->fg=1;
j->constructed=0;
j->skip_notification = is_subshell || is_block || is_event || (!is_interactive);
current_block->job = j;
j->terminal = is_interactive && !is_subshell;
current_block->job = j;
if( is_interactive )
{
if( tcgetattr (0, &j->tmodes) )

26
proc.c
View file

@ -846,22 +846,6 @@ static void read_try( job_t *j )
}
}
/**
Test if a specified job contains external commands
\param j the job to test
*/
static int job_is_external( job_t *j )
{
process_t *p;
for( p=j->first_process; p; p=p->next )
{
if( p->type == EXTERNAL )
return 1;
}
return 0;
}
void job_continue (job_t *j, int cont)
{
@ -873,7 +857,7 @@ void job_continue (job_t *j, int cont)
first_job = j;
j->notified = 0;
debug( 3,
debug( 4,
L"Continue on job %d (%ls), %ls, %ls",
j->job_id,
j->command,
@ -882,7 +866,7 @@ void job_continue (job_t *j, int cont)
if( !job_is_completed( j ) )
{
if( is_interactive && job_is_external( j ) )
if( j->terminal )
{
/* Put the job into the foreground. */
@ -937,6 +921,7 @@ void job_continue (job_t *j, int cont)
{
int quit = 0;
// debug( 1, L"wait loop" );
/*
Wait for job to report. Looks a bit ugly because it has to
handle the possibility that a signal is dispatched while
@ -953,7 +938,7 @@ void job_continue (job_t *j, int cont)
if( !quit )
{
debug( 3, L"select_try()" );
// debug( 1, L"select_try()" );
switch( select_try(j) )
{
case 1:
@ -973,6 +958,7 @@ void job_continue (job_t *j, int cont)
short-lived jobs.
*/
int status;
// debug( 1, L"waitpid" );
pid_t pid = waitpid(-1, &status, WUNTRACED );
if( pid > 0 )
handle_child_status( pid, status );
@ -1010,7 +996,7 @@ void job_continue (job_t *j, int cont)
/*
Put the shell back in the foreground.
*/
if( is_interactive && job_is_external( j ) )
if( j->terminal )
{
signal_block();
if( tcsetpgrp (0, getpid()) )

5
proc.h
View file

@ -154,7 +154,10 @@ typedef struct job
/** Skip executing this job. This flag is set by the short-circut builtins, i.e. and and or */
int skip;
/** Whether this job wants to have control of the terminal when it is in the foreground */
int terminal;
/** Pointer to the next job */
struct job *next;
}

View file

@ -2525,8 +2525,8 @@ static int read_i()
{
prev_end_loop=0;
}
error_reset();
}
reader_pop();
return 0;
@ -2829,7 +2829,7 @@ wchar_t *reader_readline()
break;
}
/* exit, but only if line is empty or the previous keypress was also an exit call */
/* exit, but only if line is empty */
case R_EXIT:
{
if( data->buff_len == 0 )