mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-23 01:24:23 +08:00
Fix the longstanding hang-on-exit bug in eterm, as well as making sure the history is saved when the terminal emulator exits
darcs-hash:20060514101623-ac50b-f8ce693ec111e3c158640ef8de309bf7e5484c5b.gz
This commit is contained in:
parent
92ecc01baa
commit
9ebdc16be6
|
@ -1857,7 +1857,7 @@ static int builtin_exit( wchar_t **argv )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
reader_exit( 1 );
|
reader_exit( 1, 0 );
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
event.c
22
event.c
|
@ -653,3 +653,25 @@ void event_free( event_t *e )
|
||||||
free( (void *)e->param1.variable );
|
free( (void *)e->param1.variable );
|
||||||
free( e );
|
free( e );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int event_signal_listen( int signal )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if( !events )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for( i=0; i<al_get_count( events ); i++ )
|
||||||
|
{
|
||||||
|
event_t *e = (event_t *)al_get( events, i );
|
||||||
|
|
||||||
|
if( e->type == EVENT_SIGNAL &&
|
||||||
|
(e->param1.signal == signal || e->param1.signal == EVENT_ANY_SIGNAL) )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
5
event.h
5
event.h
|
@ -136,4 +136,9 @@ void event_free( event_t *e );
|
||||||
*/
|
*/
|
||||||
const wchar_t *event_get_desc( event_t *e );
|
const wchar_t *event_get_desc( event_t *e );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns a non-zero status if there are event listeners that fire on the specified signal
|
||||||
|
*/
|
||||||
|
int event_signal_listen( int signal );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
9
input.c
9
input.c
|
@ -119,7 +119,8 @@ const wchar_t *name_arr[] =
|
||||||
L"history-token-search-backward",
|
L"history-token-search-backward",
|
||||||
L"history-token-search-forward",
|
L"history-token-search-forward",
|
||||||
L"self-insert",
|
L"self-insert",
|
||||||
L"null"
|
L"null",
|
||||||
|
L"eof"
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -155,7 +156,8 @@ const wchar_t *desc_arr[] =
|
||||||
L"Search backward through list of previous commands for matching token",
|
L"Search backward through list of previous commands for matching token",
|
||||||
L"Search forward through list of previous commands for matching token",
|
L"Search forward through list of previous commands for matching token",
|
||||||
L"Insert the pressed key",
|
L"Insert the pressed key",
|
||||||
L"Do nothing"
|
L"Do nothing",
|
||||||
|
L"End of file"
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -191,7 +193,8 @@ const wchar_t code_arr[] =
|
||||||
R_HISTORY_TOKEN_SEARCH_BACKWARD,
|
R_HISTORY_TOKEN_SEARCH_BACKWARD,
|
||||||
R_HISTORY_TOKEN_SEARCH_FORWARD,
|
R_HISTORY_TOKEN_SEARCH_FORWARD,
|
||||||
R_SELF_INSERT,
|
R_SELF_INSERT,
|
||||||
R_NULL
|
R_NULL,
|
||||||
|
R_EOF
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
2
input.h
2
input.h
|
@ -17,7 +17,7 @@ inputrc information for key bindings.
|
||||||
*/
|
*/
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
R_BEGINNING_OF_LINE = R_NULL+1,
|
R_BEGINNING_OF_LINE = R_NULL+10, /* This give input_common ten slots for lowlevel keycodes */
|
||||||
R_END_OF_LINE,
|
R_END_OF_LINE,
|
||||||
R_FORWARD_CHAR,
|
R_FORWARD_CHAR,
|
||||||
R_BACKWARD_CHAR,
|
R_BACKWARD_CHAR,
|
||||||
|
|
|
@ -64,7 +64,7 @@ static wint_t readb()
|
||||||
{
|
{
|
||||||
unsigned char arr[1];
|
unsigned char arr[1];
|
||||||
int do_loop = 0;
|
int do_loop = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
fd_set fd;
|
fd_set fd;
|
||||||
|
@ -93,17 +93,21 @@ static wint_t readb()
|
||||||
{
|
{
|
||||||
int res = interrupt_handler();
|
int res = interrupt_handler();
|
||||||
if( res )
|
if( res )
|
||||||
|
{
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
do_loop = 1;
|
do_loop = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
debug( 0, L"Error while reading input from keyboard, shutting down" );
|
/*
|
||||||
wperror(L"read");
|
The teminal has been closed. Save and exit.
|
||||||
exit(1);
|
*/
|
||||||
|
return R_EOF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,11 +124,12 @@ static wint_t readb()
|
||||||
}
|
}
|
||||||
if( FD_ISSET( 0, &fd ) )
|
if( FD_ISSET( 0, &fd ) )
|
||||||
{
|
{
|
||||||
if( read_blocked( 0, arr, 1 ) == -1 )
|
if( read_blocked( 0, arr, 1 ) != 1 )
|
||||||
{
|
{
|
||||||
debug( 0, L"Error while reading input from keyboard, shutting down" );
|
/*
|
||||||
wperror(L"read");
|
The teminal has been closed. Save and exit.
|
||||||
exit(1);
|
*/
|
||||||
|
return R_EOF;
|
||||||
}
|
}
|
||||||
do_loop = 0;
|
do_loop = 0;
|
||||||
}
|
}
|
||||||
|
@ -179,8 +184,8 @@ wchar_t input_common_readch( int timed )
|
||||||
|
|
||||||
int sz;
|
int sz;
|
||||||
|
|
||||||
if( b == R_NULL )
|
if( (b == R_NULL) || (b == R_EOF) )
|
||||||
return R_NULL;
|
return b;
|
||||||
|
|
||||||
bb=b;
|
bb=b;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@ enum
|
||||||
requested but none could be delivered, or when an exception
|
requested but none could be delivered, or when an exception
|
||||||
happened.
|
happened.
|
||||||
*/
|
*/
|
||||||
R_NULL = INPUT_COMMON_RESERVED
|
R_NULL = INPUT_COMMON_RESERVED,
|
||||||
|
R_EOF
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
7
main.c
7
main.c
|
@ -276,7 +276,7 @@ int main( int argc, char **argv )
|
||||||
wchar_t *cmd_wcs = str2wcs( cmd );
|
wchar_t *cmd_wcs = str2wcs( cmd );
|
||||||
res = eval( cmd_wcs, 0, TOP );
|
res = eval( cmd_wcs, 0, TOP );
|
||||||
free(cmd_wcs);
|
free(cmd_wcs);
|
||||||
reader_exit(0);
|
reader_exit(0, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -336,9 +336,9 @@ int main( int argc, char **argv )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
|
|
||||||
|
|
||||||
|
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
|
||||||
|
|
||||||
history_destroy();
|
history_destroy();
|
||||||
complete_destroy();
|
complete_destroy();
|
||||||
proc_destroy();
|
proc_destroy();
|
||||||
|
@ -355,5 +355,6 @@ int main( int argc, char **argv )
|
||||||
halloc_util_destroy();
|
halloc_util_destroy();
|
||||||
intern_free_all();
|
intern_free_all();
|
||||||
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
70
reader.c
70
reader.c
|
@ -232,6 +232,11 @@ typedef struct reader_data
|
||||||
When this is true, the reader will exit
|
When this is true, the reader will exit
|
||||||
*/
|
*/
|
||||||
int end_loop;
|
int end_loop;
|
||||||
|
/**
|
||||||
|
If this is true, exit reader even if there are running
|
||||||
|
jobs. This happens if we press e.g. ^D twice.
|
||||||
|
*/
|
||||||
|
int prev_end_loop;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Pointer to previous reader_data
|
Pointer to previous reader_data
|
||||||
|
@ -299,6 +304,11 @@ static void reader_save_status();
|
||||||
static void reader_check_status();
|
static void reader_check_status();
|
||||||
static void reader_super_highlight_me_plenty( wchar_t * buff, int *color, int pos, array_list_t *error );
|
static void reader_super_highlight_me_plenty( wchar_t * buff, int *color, int pos, array_list_t *error );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Variable to keep track of forced exits - see \c reader_exit_forced();
|
||||||
|
*/
|
||||||
|
static int exit_forced;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Give up control of terminal
|
Give up control of terminal
|
||||||
|
@ -370,6 +380,12 @@ static int room_for_usec(struct stat *st)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int reader_exit_forced()
|
||||||
|
{
|
||||||
|
return exit_forced;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
string_buffer used as temporary storage for the reader_readline function
|
string_buffer used as temporary storage for the reader_readline function
|
||||||
*/
|
*/
|
||||||
|
@ -869,11 +885,14 @@ void reader_destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void reader_exit( int do_exit )
|
void reader_exit( int do_exit, int forced )
|
||||||
{
|
{
|
||||||
if( data )
|
if( data )
|
||||||
data->end_loop=do_exit;
|
data->end_loop=do_exit;
|
||||||
end_loop=do_exit;
|
end_loop=do_exit;
|
||||||
|
if( forced )
|
||||||
|
exit_forced = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void repaint()
|
void repaint()
|
||||||
|
@ -2230,7 +2249,6 @@ int exit_status()
|
||||||
*/
|
*/
|
||||||
static int read_i()
|
static int read_i()
|
||||||
{
|
{
|
||||||
int prev_end_loop=0;
|
|
||||||
|
|
||||||
reader_push(L"fish");
|
reader_push(L"fish");
|
||||||
reader_set_complete_function( &complete );
|
reader_set_complete_function( &complete );
|
||||||
|
@ -2238,6 +2256,7 @@ static int read_i()
|
||||||
reader_set_test_function( &shell_test );
|
reader_set_test_function( &shell_test );
|
||||||
|
|
||||||
data->prompt_width=60;
|
data->prompt_width=60;
|
||||||
|
data->prev_end_loop=0;
|
||||||
|
|
||||||
while( (!data->end_loop) && (!sanity_check()) )
|
while( (!data->end_loop) && (!sanity_check()) )
|
||||||
{
|
{
|
||||||
|
@ -2254,12 +2273,7 @@ static int read_i()
|
||||||
during evaluation.
|
during evaluation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tmp = wcsdup( reader_readline() );
|
tmp = reader_readline();
|
||||||
|
|
||||||
data->buff_pos=data->buff_len=0;
|
|
||||||
data->buff[data->buff_len]=L'\0';
|
|
||||||
reader_run_command( tmp );
|
|
||||||
free( tmp );
|
|
||||||
|
|
||||||
if( data->end_loop)
|
if( data->end_loop)
|
||||||
{
|
{
|
||||||
|
@ -2275,17 +2289,24 @@ static int read_i()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !prev_end_loop && has_job )
|
if( !reader_exit_forced() && !data->prev_end_loop && has_job )
|
||||||
{
|
{
|
||||||
writestr(_( L"There are stopped jobs\n" ));
|
writestr(_( L"There are stopped jobs\n" ));
|
||||||
write_prompt();
|
write_prompt();
|
||||||
data->end_loop = 0;
|
data->end_loop = 0;
|
||||||
prev_end_loop=1;
|
data->prev_end_loop=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prev_end_loop=0;
|
tmp = wcsdup( tmp );
|
||||||
|
|
||||||
|
data->buff_pos=data->buff_len=0;
|
||||||
|
data->buff[data->buff_len]=L'\0';
|
||||||
|
reader_run_command( tmp );
|
||||||
|
free( tmp );
|
||||||
|
|
||||||
|
data->prev_end_loop=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2442,6 +2463,14 @@ wchar_t *reader_readline()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case R_EOF:
|
||||||
|
{
|
||||||
|
exit_forced = 1;
|
||||||
|
data->end_loop=1;
|
||||||
|
debug( 1, L"got R_EOF" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* complete */
|
/* complete */
|
||||||
case R_COMPLETE:
|
case R_COMPLETE:
|
||||||
{
|
{
|
||||||
|
@ -2833,14 +2862,17 @@ wchar_t *reader_readline()
|
||||||
}
|
}
|
||||||
|
|
||||||
al_destroy( &comp );
|
al_destroy( &comp );
|
||||||
if( tcsetattr(0,TCSANOW,&old_modes)) /* return to previous mode */
|
if( !reader_exit_forced() )
|
||||||
{
|
{
|
||||||
wperror(L"tcsetattr");
|
if( tcsetattr(0,TCSANOW,&old_modes)) /* return to previous mode */
|
||||||
exit(1);
|
{
|
||||||
}
|
wperror(L"tcsetattr");
|
||||||
|
exit(1);
|
||||||
set_color( FISH_COLOR_RESET, FISH_COLOR_RESET );
|
}
|
||||||
|
|
||||||
|
set_color( FISH_COLOR_RESET, FISH_COLOR_RESET );
|
||||||
|
}
|
||||||
|
|
||||||
return data->buff;
|
return data->buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
7
reader.h
7
reader.h
|
@ -21,7 +21,7 @@ int reader_read( int fd);
|
||||||
/**
|
/**
|
||||||
Tell the shell that it should exit after the currently running command finishes.
|
Tell the shell that it should exit after the currently running command finishes.
|
||||||
*/
|
*/
|
||||||
void reader_exit( int do_exit );
|
void reader_exit( int do_exit, int force );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check that the reader is in a sane state
|
Check that the reader is in a sane state
|
||||||
|
@ -162,5 +162,10 @@ void reader_replace_current_token( wchar_t *new_token );
|
||||||
*/
|
*/
|
||||||
void reader_handle_int( int signal );
|
void reader_handle_int( int signal );
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function returns true if fish is exiting by force, i.e. because stdin died
|
||||||
|
*/
|
||||||
|
int reader_exit_forced();
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
28
signal.c
28
signal.c
|
@ -367,6 +367,7 @@ const wchar_t *signal_get_desc( int sig )
|
||||||
static void default_handler(int signal, siginfo_t *info, void *context)
|
static void default_handler(int signal, siginfo_t *info, void *context)
|
||||||
{
|
{
|
||||||
event_t e;
|
event_t e;
|
||||||
|
|
||||||
e.type=EVENT_SIGNAL;
|
e.type=EVENT_SIGNAL;
|
||||||
e.param1.signal = signal;
|
e.param1.signal = signal;
|
||||||
e.function_name=0;
|
e.function_name=0;
|
||||||
|
@ -383,6 +384,22 @@ static void handle_winch( int sig, siginfo_t *info, void *context )
|
||||||
default_handler( sig, 0, 0 );
|
default_handler( sig, 0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Respond to a winch signal by checking the terminal size
|
||||||
|
*/
|
||||||
|
static void handle_hup( int sig, siginfo_t *info, void *context )
|
||||||
|
{
|
||||||
|
if( event_signal_listen( SIGHUP ) )
|
||||||
|
{
|
||||||
|
default_handler( sig, 0, 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reader_exit( 1, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Interactive mode ^C handler. Respond to int signal by setting
|
Interactive mode ^C handler. Respond to int signal by setting
|
||||||
interrupted-flag and stopping all loops and conditionals.
|
interrupted-flag and stopping all loops and conditionals.
|
||||||
|
@ -479,7 +496,7 @@ void signal_set_handlers()
|
||||||
wperror( L"sigaction" );
|
wperror( L"sigaction" );
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
act.sa_flags = SA_SIGINFO;
|
act.sa_flags = SA_SIGINFO;
|
||||||
act.sa_sigaction= &handle_winch;
|
act.sa_sigaction= &handle_winch;
|
||||||
if( sigaction( SIGWINCH, &act, 0 ) )
|
if( sigaction( SIGWINCH, &act, 0 ) )
|
||||||
|
@ -488,6 +505,14 @@ void signal_set_handlers()
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
act.sa_flags = SA_SIGINFO;
|
||||||
|
act.sa_sigaction= &handle_hup;
|
||||||
|
if( sigaction( SIGHUP, &act, 0 ) )
|
||||||
|
{
|
||||||
|
wperror( L"sigaction" );
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -510,6 +535,7 @@ void signal_set_handlers()
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void signal_handle( int sig, int do_handle )
|
void signal_handle( int sig, int do_handle )
|
||||||
|
|
Loading…
Reference in New Issue
Block a user