diff options
-rw-r--r-- | event.c | 4 | ||||
-rw-r--r-- | exec.c | 14 | ||||
-rw-r--r-- | input.c | 20 | ||||
-rw-r--r-- | parser.c | 7 | ||||
-rw-r--r-- | proc.c | 26 | ||||
-rw-r--r-- | proc.h | 5 | ||||
-rw-r--r-- | reader.c | 4 |
7 files changed, 44 insertions, 36 deletions
@@ -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 { @@ -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; } @@ -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; } @@ -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) ) @@ -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()) ) @@ -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; } @@ -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 ) |