From 05736978bb5621d33d9b34467a278f6cca095940 Mon Sep 17 00:00:00 2001 From: axel Date: Wed, 18 Jan 2006 22:42:48 +1000 Subject: [PATCH] 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 --- event.c | 4 ---- exec.c | 14 ++++++++------ input.c | 20 ++++++++++++++++++++ parser.c | 7 ++++--- proc.c | 26 ++++++-------------------- proc.h | 5 ++++- reader.c | 4 ++-- 7 files changed, 44 insertions(+), 36 deletions(-) diff --git a/event.c b/event.c index b2ce66559..f2232d3c8 100644 --- a/event.c +++ b/event.c @@ -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 { diff --git a/exec.c b/exec.c index b25b9b746..8fc494486 100644 --- a/exec.c +++ b/exec.c @@ -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; } diff --git a/input.c b/input.c index 3dc701687..8da2fa626 100644 --- a/input.c +++ b/input.c @@ -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; } diff --git a/parser.c b/parser.c index f1b72f056..b7d91408a 100644 --- a/parser.c +++ b/parser.c @@ -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) ) diff --git a/proc.c b/proc.c index 1942f7450..3536d56d8 100644 --- a/proc.c +++ b/proc.c @@ -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()) ) diff --git a/proc.h b/proc.h index b26b31e54..f4e10bd2e 100644 --- a/proc.h +++ b/proc.h @@ -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; } diff --git a/reader.c b/reader.c index 1f20ce14c..04ac371c2 100644 --- a/reader.c +++ b/reader.c @@ -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 )