Make fish send a HUP signal to jobs when the terminal tells it to exit.

darcs-hash:20061111104840-ac50b-ae989e26bdb6c769ed93dcf11b742887c97858aa.gz
This commit is contained in:
axel 2006-11-11 20:48:40 +10:00
parent fb62a35921
commit 5f69f2bb0c
4 changed files with 137 additions and 67 deletions

1
main.c
View file

@ -290,6 +290,7 @@ int main( int argc, char **argv )
is_interactive_session=1; is_interactive_session=1;
program_name=L"fish"; program_name=L"fish";
my_optind = fish_parse_opt( argc, argv, &cmd ); my_optind = fish_parse_opt( argc, argv, &cmd );
/* /*

154
proc.c
View file

@ -189,7 +189,6 @@ void proc_destroy()
void proc_set_last_status( int s ) void proc_set_last_status( int s )
{ {
last_status = s; last_status = s;
// debug( 0, L"Set last status to %d\n", 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 ) int status )
{ {
p->status = 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)) if (WIFSTOPPED (status))
{ {
p->stopped = 1; p->stopped = 1;
@ -320,6 +321,7 @@ static void mark_process_status( job_t *j,
{ {
p->completed = 1; p->completed = 1;
if (( !WIFEXITED( status ) ) && if (( !WIFEXITED( status ) ) &&
(! WIFSIGNALED( status )) ) (! WIFSIGNALED( status )) )
{ {
@ -848,29 +850,9 @@ static void read_try( job_t *j )
} }
void job_continue (job_t *j, int cont) static int terminal_give_to_job( job_t *j, int cont )
{ {
/*
Put job first in the job list
*/
job_remove( j );
j->next = first_job;
first_job = j;
job_set_flag( j, JOB_NOTIFIED, 0 );
debug( 3,
L"Continue job %d (%ls), %ls, %ls",
j->job_id,
j->command,
job_is_completed( j )?L"COMPLETED":L"UNCOMPLETED",
is_interactive?L"INTERACTIVE":L"NON-INTERACTIVE" );
if( !job_is_completed( j ) )
{
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) ) if( tcsetpgrp (0, j->pgid) )
{ {
debug( 1, debug( 1,
@ -878,7 +860,7 @@ void job_continue (job_t *j, int cont)
j->job_id, j->job_id,
j->command ); j->command );
wperror( L"tcsetpgrp" ); wperror( L"tcsetpgrp" );
return; return 0;
} }
if( cont ) if( cont )
@ -890,10 +872,84 @@ void job_continue (job_t *j, int cont)
j->job_id, j->job_id,
j->command ); j->command );
wperror( L"tcsetattr" ); wperror( L"tcsetattr" );
return; 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)
{
/*
Put job first in the job list
*/
job_remove( j );
j->next = first_job;
first_job = j;
job_set_flag( j, JOB_NOTIFIED, 0 );
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" );
if( !job_is_completed( j ) )
{
if( job_get_flag( j, JOB_TERMINAL ) && job_get_flag( j, JOB_FOREGROUND ) )
{
/* Put the job into the foreground. */
int ok;
signal_block();
ok = terminal_give_to_job( j, cont );
signal_unblock(); signal_unblock();
if( !ok )
return;
} }
/* /*
@ -967,10 +1023,27 @@ void job_continue (job_t *j, int cont)
short-lived jobs. short-lived jobs.
*/ */
int status; int status;
// debug( 1, L"waitpid" );
pid_t pid = waitpid(-1, &status, WUNTRACED ); pid_t pid = waitpid(-1, &status, WUNTRACED );
if( pid > 0 ) if( pid > 0 )
{
handle_child_status( pid, status ); 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; 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 ) ) if( job_get_flag( j, JOB_TERMINAL ) && job_get_flag( j, JOB_FOREGROUND ) )
{ {
int ok;
signal_block(); 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(); signal_unblock();
if( !ok )
return;
} }
} }

View file

@ -275,10 +275,6 @@ static pid_t original_pid;
*/ */
static int interrupted=0; 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. Prototypes for a bunch of functions defined later on.
@ -303,8 +299,6 @@ static int exit_forced;
*/ */
static void term_donate() static void term_donate()
{ {
tcgetattr(0,&old_modes); /* get the current terminal modes */
set_color(FISH_COLOR_NORMAL, FISH_COLOR_NORMAL); set_color(FISH_COLOR_NORMAL, FISH_COLOR_NORMAL);
while( 1 ) while( 1 )
@ -348,12 +342,6 @@ static void term_steal()
common_handle_winch(0 ); common_handle_winch(0 );
if( tcsetattr(0,TCSANOW,&old_modes))/* return to previous mode */
{
wperror(L"tcsetattr");
exit(1);
}
} }
int reader_exit_forced() int reader_exit_forced()
@ -1210,7 +1198,6 @@ static void reader_interactive_init()
if( tcsetattr(0,TCSANOW,&shell_modes)) /* set the new modes */ if( tcsetattr(0,TCSANOW,&shell_modes)) /* set the new modes */
{ {
wperror(L"tcsetattr"); wperror(L"tcsetattr");
exit(1);
} }
/* /*
@ -1911,6 +1898,34 @@ static int read_i()
repaint(); 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 else
{ {
@ -1986,7 +2001,6 @@ wchar_t *reader_readline()
if( tcsetattr(0,TCSANOW,&shell_modes)) if( tcsetattr(0,TCSANOW,&shell_modes))
{ {
wperror(L"tcsetattr"); wperror(L"tcsetattr");
exit(1);
} }
while( !finished && !data->end_loop) while( !finished && !data->end_loop)
@ -2564,7 +2578,6 @@ wchar_t *reader_readline()
if( tcsetattr(0,TCSANOW,&old_modes)) /* return to previous mode */ if( tcsetattr(0,TCSANOW,&old_modes)) /* return to previous mode */
{ {
wperror(L"tcsetattr"); wperror(L"tcsetattr");
exit(1);
} }
set_color( FISH_COLOR_RESET, FISH_COLOR_RESET ); set_color( FISH_COLOR_RESET, FISH_COLOR_RESET );