From 5f69f2bb0cc593e158541a5951fcd8277428bd99 Mon Sep 17 00:00:00 2001 From: axel Date: Sat, 11 Nov 2006 20:48:40 +1000 Subject: [PATCH] Make fish send a HUP signal to jobs when the terminal tells it to exit. darcs-hash:20061111104840-ac50b-ae989e26bdb6c769ed93dcf11b742887c97858aa.gz --- main.c | 1 + proc.c | 158 +++++++++++++++++++++++++++++++++++++------------------ reader.c | 43 +++++++++------ signal.c | 2 +- 4 files changed, 137 insertions(+), 67 deletions(-) diff --git a/main.c b/main.c index 7c5f5d919..a55f834df 100644 --- a/main.c +++ b/main.c @@ -290,6 +290,7 @@ int main( int argc, char **argv ) is_interactive_session=1; program_name=L"fish"; + my_optind = fish_parse_opt( argc, argv, &cmd ); /* diff --git a/proc.c b/proc.c index fa1c660bb..a4644d764 100644 --- a/proc.c +++ b/proc.c @@ -189,7 +189,6 @@ void proc_destroy() void proc_set_last_status( int s ) { - last_status = s; // debug( 0, L"Set last status to %d\n", s ); } @@ -312,6 +311,8 @@ static void mark_process_status( job_t *j, int status ) { p->status = status; +// debug( 0, L"Process %ls %ls", p->argv[0], WIFSTOPPED (status)?L"stopped":(WIFEXITED( status )?L"exited":(WIFSIGNALED( status )?L"signaled to exit":L"BLARGH")) ); + if (WIFSTOPPED (status)) { p->stopped = 1; @@ -319,6 +320,7 @@ static void mark_process_status( job_t *j, else { p->completed = 1; + if (( !WIFEXITED( status ) ) && (! WIFSIGNALED( status )) ) @@ -848,6 +850,70 @@ static void read_try( job_t *j ) } +static int terminal_give_to_job( job_t *j, int cont ) +{ + + if( tcsetpgrp (0, j->pgid) ) + { + debug( 1, + _( L"Could not send job %d ('%ls') to foreground" ), + j->job_id, + j->command ); + wperror( L"tcsetpgrp" ); + return 0; + } + + if( cont ) + { + if( tcsetattr (0, TCSADRAIN, &j->tmodes)) + { + debug( 1, + _( L"Could not send job %d ('%ls') to foreground" ), + j->job_id, + j->command ); + wperror( L"tcsetattr" ); + return 0; + } + } + return 1; +} + +/** + REturns contol of the terminal +*/ +static int terminal_return_from_job( job_t *j) +{ + + if( tcsetpgrp (0, getpid()) ) + { + debug( 1, _( L"Could not return shell to foreground" ) ); + wperror( L"tcsetpgrp" ); + return 0; + } + + /* + Save jobs terminal modes. + */ + if( tcgetattr (0, &j->tmodes) ) + { + debug( 1, _( L"Could not return shell to foreground" ) ); + wperror( L"tcgetattr" ); + return 0; + } + + /* + Restore the shell's terminal modes. + */ + if( tcsetattr (0, TCSADRAIN, &shell_modes)) + { + debug( 1, _( L"Could not return shell to foreground" ) ); + wperror( L"tcsetattr" ); + return 0; + } + + return 1; +} + void job_continue (job_t *j, int cont) { /* @@ -858,9 +924,12 @@ void job_continue (job_t *j, int cont) first_job = j; job_set_flag( j, JOB_NOTIFIED, 0 ); - debug( 3, - L"Continue job %d (%ls), %ls, %ls", + CHECK_BLOCK(); + + debug( 4, + L"Continue job %d, gid %d (%ls), %ls, %ls", j->job_id, + j->pgid, j->command, job_is_completed( j )?L"COMPLETED":L"UNCOMPLETED", is_interactive?L"INTERACTIVE":L"NON-INTERACTIVE" ); @@ -870,30 +939,17 @@ void job_continue (job_t *j, int cont) if( job_get_flag( j, JOB_TERMINAL ) && job_get_flag( j, JOB_FOREGROUND ) ) { /* Put the job into the foreground. */ - signal_block(); - if( tcsetpgrp (0, j->pgid) ) - { - debug( 1, - _( L"Could not send job %d ('%ls') to foreground" ), - j->job_id, - j->command ); - wperror( L"tcsetpgrp" ); - return; - } + int ok; + + signal_block(); + + ok = terminal_give_to_job( j, cont ); - if( cont ) - { - if( tcsetattr (0, TCSADRAIN, &j->tmodes)) - { - debug( 1, - _( L"Could not send job %d ('%ls') to foreground" ), - j->job_id, - j->command ); - wperror( L"tcsetattr" ); - return; - } - } signal_unblock(); + + if( !ok ) + return; + } /* @@ -967,10 +1023,27 @@ 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 ); + } + else + { + /* + This probably means we got a + signal. A signal might mean that the + terminal emulator sent us a hup + signal to tell is to close. If so, + we should exit. + */ + if( reader_exit_forced() ) + { + quit = 1; + } + + } + break; } @@ -1007,34 +1080,17 @@ void job_continue (job_t *j, int cont) */ if( job_get_flag( j, JOB_TERMINAL ) && job_get_flag( j, JOB_FOREGROUND ) ) { + int ok; + signal_block(); - if( tcsetpgrp (0, getpid()) ) - { - debug( 1, _( L"Could not return shell to foreground" ) ); - wperror( L"tcsetpgrp" ); - return; - } + + ok = terminal_return_from_job( j ); - /* - Save jobs terminal modes. - */ - if( tcgetattr (0, &j->tmodes) ) - { - debug( 1, _( L"Could not return shell to foreground" ) ); - wperror( L"tcgetattr" ); - return; - } - - /* - Restore the shell's terminal modes. - */ - if( tcsetattr (0, TCSADRAIN, &shell_modes)) - { - debug( 1, _( L"Could not return shell to foreground" ) ); - wperror( L"tcsetattr" ); - return; - } signal_unblock(); + + if( !ok ) + return; + } } diff --git a/reader.c b/reader.c index e7c37c6c9..77fa02336 100644 --- a/reader.c +++ b/reader.c @@ -275,10 +275,6 @@ static pid_t original_pid; */ static int interrupted=0; -/** - Original terminal mode when fish was started -*/ -static struct termios old_modes; /* Prototypes for a bunch of functions defined later on. @@ -303,8 +299,6 @@ static int exit_forced; */ static void term_donate() { - tcgetattr(0,&old_modes); /* get the current terminal modes */ - set_color(FISH_COLOR_NORMAL, FISH_COLOR_NORMAL); while( 1 ) @@ -348,12 +342,6 @@ static void term_steal() common_handle_winch(0 ); - if( tcsetattr(0,TCSANOW,&old_modes))/* return to previous mode */ - { - wperror(L"tcsetattr"); - exit(1); - } - } int reader_exit_forced() @@ -1210,7 +1198,6 @@ static void reader_interactive_init() if( tcsetattr(0,TCSANOW,&shell_modes)) /* set the new modes */ { wperror(L"tcsetattr"); - exit(1); } /* @@ -1911,6 +1898,34 @@ static int read_i() repaint(); } + else + { + pid_t my_pid = getpid(); + for( j = first_job; j; j=j->next ) + { + if( ! job_is_completed( j ) ) + { + if( j->pgid != my_pid ) + { + killpg( j->pgid, SIGHUP ); + } + else + { + process_t *p; + for( p = j->first_process; p; p=p->next ) + { + if( ! p->completed ) + { + if( p->pid ) + { + kill( p->pid, SIGHUP ); + } + } + } + } + } + } + } } else { @@ -1986,7 +2001,6 @@ wchar_t *reader_readline() if( tcsetattr(0,TCSANOW,&shell_modes)) { wperror(L"tcsetattr"); - exit(1); } while( !finished && !data->end_loop) @@ -2564,7 +2578,6 @@ wchar_t *reader_readline() if( tcsetattr(0,TCSANOW,&old_modes)) /* return to previous mode */ { wperror(L"tcsetattr"); - exit(1); } set_color( FISH_COLOR_RESET, FISH_COLOR_RESET ); diff --git a/signal.c b/signal.c index 45630208e..e18c5cdc2 100644 --- a/signal.c +++ b/signal.c @@ -459,7 +459,7 @@ static void handle_hup( int sig, siginfo_t *info, void *context ) e.type=EVENT_SIGNAL; e.param1.signal = SIGHUP; e.function_name=0; - + if( event_get( &e, 0 ) ) { default_handler( sig, 0, 0 );