From 0de232bf549301058efd3c161b204f79e3ab4177 Mon Sep 17 00:00:00 2001 From: axel Date: Tue, 4 Apr 2006 21:27:22 +1000 Subject: [PATCH] Do not return to the shell until all processes of a job have finished (Previous behaviour was to return once the last job had exited, and could cause e.g. the jobs builtin to print out the job responsible for repainting the titlebar). Also validate that jobs have not completed in various places where the job list is examined darcs-hash:20060404112722-ac50b-4b6a55ce7c57d39213cdd0ed0f581795a72859b7.gz --- builtin.c | 6 +++--- exec.c | 4 +--- parser.c | 1 - proc.c | 30 ++++++++++++------------------ reader.c | 14 +++++++++++++- 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/builtin.c b/builtin.c index 9858446df..fa64356d7 100644 --- a/builtin.c +++ b/builtin.c @@ -2503,7 +2503,7 @@ static int builtin_jobs( wchar_t **argv ) */ for( j=first_job; j; j=j->next ) { - if( j->constructed ) + if( j->constructed && !job_is_completed(j) ) { builtin_jobs_print( j, mode, !found ); return 0; @@ -2536,7 +2536,7 @@ static int builtin_jobs( wchar_t **argv ) j = job_get_from_pid( pid ); - if( j ) + if( j && !job_is_completed( j ) ) { builtin_jobs_print( j, mode, !found ); } @@ -2557,7 +2557,7 @@ static int builtin_jobs( wchar_t **argv ) /* Ignore unconstructed jobs, i.e. ourself. */ - if( j->constructed /*&& j->skip_notification*/ ) + if( j->constructed && !job_is_completed(j) ) { builtin_jobs_print( j, mode, !found ); found = 1; diff --git a/exec.c b/exec.c index e93731608..949a97703 100644 --- a/exec.c +++ b/exec.c @@ -1209,14 +1209,12 @@ void exec( job_t *j ) { proc_last_bg_pid = j->pgid; } - + if( !exec_error ) { job_continue (j, 0); } - debug( 3, L"End of exec()" ); - } int exec_subshell( const wchar_t *cmd, diff --git a/parser.c b/parser.c index 0d8368251..9c88efe69 100644 --- a/parser.c +++ b/parser.c @@ -2497,7 +2497,6 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type ) return code; } - int parser_test( wchar_t * buff, int babble ) { diff --git a/proc.c b/proc.c index 799cf2e1b..79e89950a 100644 --- a/proc.c +++ b/proc.c @@ -265,28 +265,12 @@ int job_is_completed( const job_t *j ) { if (!p->completed) { -// fwprintf( stderr, L"Process %ls not finished\n", p->argv[0] ); return 0; } } return 1; } -/** - Return true if all processes in the job have completed. - - \param j the job to test -*/ -static int job_last_is_completed( const job_t *j ) -{ - process_t *p; - - for (p = j->first_process; p->next; p = p->next) - ; - return p->completed; -} - - /** Store the status of the process pid that was returned by waitpid. Return 0 if all went well, nonzero otherwise. @@ -503,6 +487,11 @@ int job_reap( int interactive ) static int locked = 0; locked++; + + /* + job_read may fire an event handler, we do not want to call + ourselves recursively (to avoid infinite recursion). + */ if( locked>1 ) return 0; @@ -511,6 +500,11 @@ int job_reap( int interactive ) process_t *p; jnext = j->next; + /* + If we are reaping only jobs who do not need status messages + sent to the console, do not consider reaping jobs that need + status messages + */ if( (!j->skip_notification) && (!interactive) && (!j->fg)) { continue; @@ -915,7 +909,7 @@ void job_continue (job_t *j, int cont) do { got_signal = 0; - quit = job_is_stopped( j ) || job_last_is_completed( j ); + quit = job_is_stopped( j ) || job_is_completed( j ); } while( got_signal && !quit ); if( !quit ) @@ -1039,7 +1033,7 @@ void proc_sanity_check() /* More than one foreground job? */ - if( j->fg && !(job_is_stopped(j) || job_last_is_completed(j) ) ) + if( j->fg && !(job_is_stopped(j) || job_is_completed(j) ) ) { if( fg_job != 0 ) { diff --git a/reader.c b/reader.c index 07ba4ef2f..48e7834e7 100644 --- a/reader.c +++ b/reader.c @@ -2265,7 +2265,19 @@ static int read_i() if( data->end_loop) { - if( !prev_end_loop && first_job != 0 ) + job_t *j; + int has_job=0; + + for( j=first_job; j; j=j->next ) + { + if( !job_is_completed(j) ) + { + has_job = 1; + break; + } + } + + if( !prev_end_loop && has_job ) { writestr(_( L"There are stopped jobs\n" )); write_prompt();