mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
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:
parent
fb62a35921
commit
5f69f2bb0c
4 changed files with 137 additions and 67 deletions
1
main.c
1
main.c
|
@ -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
154
proc.c
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
43
reader.c
43
reader.c
|
@ -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 );
|
||||||
|
|
Loading…
Reference in a new issue