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:
axel 2006-05-14 20:16:23 +10:00
parent 92ecc01baa
commit 9ebdc16be6
12 changed files with 141 additions and 40 deletions

View File

@ -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
View File

@ -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;
}

View File

@ -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

View File

@ -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
} }
; ;

View File

@ -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,

View File

@ -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;

View File

@ -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
} }
; ;

3
main.c
View File

@ -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
{ {
@ -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;
} }

View File

@ -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,6 +2862,8 @@ wchar_t *reader_readline()
} }
al_destroy( &comp ); al_destroy( &comp );
if( !reader_exit_forced() )
{
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");
@ -2840,6 +2871,7 @@ wchar_t *reader_readline()
} }
set_color( FISH_COLOR_RESET, FISH_COLOR_RESET ); set_color( FISH_COLOR_RESET, FISH_COLOR_RESET );
}
return data->buff; return data->buff;
} }

View File

@ -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

View File

@ -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.
@ -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 )

1
util.c
View File

@ -809,6 +809,7 @@ int wcsfilecmp( const wchar_t *a, const wchar_t *b )
{ {
return 1; return 1;
} }
int secondary_diff=0; int secondary_diff=0;
if( iswdigit( *a ) && iswdigit( *b ) ) if( iswdigit( *a ) && iswdigit( *b ) )
{ {