mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Fix bug in fish causing occasionally incorrect signal handlers
darcs-hash:20060216133632-ac50b-f24c049830f9c6deca50aca640189ad3f87b630a.gz
This commit is contained in:
parent
777a559e12
commit
cc69afc4fe
7 changed files with 61 additions and 37 deletions
|
@ -1338,16 +1338,15 @@ static void complete_from_args( const wchar_t *str,
|
|||
const wchar_t *desc,
|
||||
array_list_t *comp_out )
|
||||
{
|
||||
int was_interactive = is_interactive;
|
||||
|
||||
array_list_t possible_comp;
|
||||
int i;
|
||||
|
||||
al_init( &possible_comp );
|
||||
|
||||
is_interactive=0;
|
||||
proc_push_interactive(0);
|
||||
eval_args( args, &possible_comp );
|
||||
is_interactive=was_interactive;
|
||||
proc_pop_interactive();
|
||||
|
||||
/* We need to unescape these strings before matching them */
|
||||
for( i=0; i< al_get_count( &possible_comp ); i++ )
|
||||
|
|
11
event.c
11
event.c
|
@ -386,8 +386,6 @@ static void event_fire_internal( event_t *event )
|
|||
string_buffer_t *b=0;
|
||||
array_list_t *fire=0;
|
||||
|
||||
int was_interactive = is_interactive;
|
||||
|
||||
/*
|
||||
First we free all events that have been removed
|
||||
*/
|
||||
|
@ -462,19 +460,14 @@ static void event_fire_internal( event_t *event )
|
|||
Event handlers are not part of the main flow of code, so
|
||||
they are marked as non-interactive and as a subshell
|
||||
*/
|
||||
is_interactive=0;
|
||||
proc_push_interactive(0);
|
||||
parser_push_block( EVENT );
|
||||
current_block->param1.event = event;
|
||||
eval( (wchar_t *)b->buff, 0, TOP );
|
||||
parser_pop_block();
|
||||
|
||||
proc_pop_interactive();
|
||||
}
|
||||
|
||||
/*
|
||||
Restore interactivity flags
|
||||
*/
|
||||
is_interactive = was_interactive;
|
||||
|
||||
if( b )
|
||||
{
|
||||
sb_destroy( b );
|
||||
|
|
6
parser.c
6
parser.c
|
@ -917,9 +917,9 @@ int eval_args( const wchar_t *line, array_list_t *args )
|
|||
tokenizer *previous_tokenizer=current_tokenizer;
|
||||
int previous_pos=current_tokenizer_pos;
|
||||
int do_loop=1;
|
||||
int was_interactive = is_interactive;
|
||||
|
||||
is_interactive = 0;
|
||||
proc_push_interactive(0);
|
||||
|
||||
current_tokenizer_pos = 0;
|
||||
|
||||
tok_init( &tok, line, 0 );
|
||||
|
@ -978,7 +978,7 @@ int eval_args( const wchar_t *line, array_list_t *args )
|
|||
|
||||
current_tokenizer=previous_tokenizer;
|
||||
current_tokenizer_pos = previous_pos;
|
||||
is_interactive = was_interactive;
|
||||
proc_pop_interactive();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
23
proc.c
23
proc.c
|
@ -54,6 +54,8 @@ Some of the code in this file is based on code from the Glibc manual.
|
|||
#include "event.h"
|
||||
#include "translate.h"
|
||||
#include "halloc.h"
|
||||
#include "halloc_util.h"
|
||||
#include "output.h"
|
||||
|
||||
/**
|
||||
Size of message buffer
|
||||
|
@ -76,7 +78,7 @@ static int last_status=0;
|
|||
static sig_atomic_t got_signal=0;
|
||||
|
||||
job_t *first_job=0;
|
||||
int is_interactive=0;
|
||||
int is_interactive=-1;
|
||||
int is_interactive_session=0;
|
||||
int is_subshell=0;
|
||||
int is_block=0;
|
||||
|
@ -101,9 +103,12 @@ static string_buffer_t event_pid;
|
|||
*/
|
||||
static string_buffer_t event_status;
|
||||
|
||||
static array_list_t *interactive_stack;
|
||||
|
||||
void proc_init()
|
||||
{
|
||||
interactive_stack = al_halloc( global_context );
|
||||
proc_push_interactive( 0 );
|
||||
al_init( &event.arguments );
|
||||
sb_init( &event_pid );
|
||||
sb_init( &event_status );
|
||||
|
@ -1077,3 +1082,19 @@ void proc_sanity_check()
|
|||
}
|
||||
}
|
||||
|
||||
void proc_push_interactive( int value )
|
||||
{
|
||||
int old = is_interactive;
|
||||
al_push( interactive_stack, (void *)(long)is_interactive );
|
||||
is_interactive = value;
|
||||
if( old != value )
|
||||
signal_set_handlers();
|
||||
}
|
||||
|
||||
void proc_pop_interactive()
|
||||
{
|
||||
int old = is_interactive;
|
||||
is_interactive= (int)(long)al_pop(interactive_stack);
|
||||
if( is_interactive != old )
|
||||
signal_set_handlers();
|
||||
}
|
||||
|
|
12
proc.h
12
proc.h
|
@ -337,4 +337,16 @@ void proc_init();
|
|||
*/
|
||||
void proc_destroy();
|
||||
|
||||
/**
|
||||
Set new value for is_interactive flag, saving previous value. If
|
||||
needed, update signal handlers.
|
||||
*/
|
||||
void proc_push_interactive( int value );
|
||||
|
||||
/**
|
||||
Set is_interactive flag to the previous value. If needed, update
|
||||
signal handlers.
|
||||
*/
|
||||
void proc_pop_interactive();
|
||||
|
||||
#endif
|
||||
|
|
18
reader.c
18
reader.c
|
@ -606,7 +606,6 @@ void reader_write_title()
|
|||
wchar_t *title;
|
||||
array_list_t l;
|
||||
wchar_t *term = env_get( L"TERM" );
|
||||
int was_interactive = is_interactive;
|
||||
|
||||
/*
|
||||
This is a pretty lame heuristic for detecting terminals that do
|
||||
|
@ -628,7 +627,7 @@ void reader_write_title()
|
|||
|
||||
al_init( &l );
|
||||
|
||||
is_interactive = 0;
|
||||
proc_push_interactive(0);
|
||||
if( exec_subshell( title, &l ) != -1 )
|
||||
{
|
||||
int i;
|
||||
|
@ -639,7 +638,7 @@ void reader_write_title()
|
|||
}
|
||||
writestr( L"\7" );
|
||||
}
|
||||
is_interactive = was_interactive;
|
||||
proc_pop_interactive();
|
||||
|
||||
al_foreach( &l, (void (*)(const void *))&free );
|
||||
al_destroy( &l );
|
||||
|
@ -790,8 +789,8 @@ static void write_prompt()
|
|||
|
||||
if( data->prompt )
|
||||
{
|
||||
int was_interactive = is_interactive;
|
||||
is_interactive = 0;
|
||||
proc_push_interactive( 0 );
|
||||
|
||||
if( exec_subshell( data->prompt, &prompt_list ) == -1 )
|
||||
{
|
||||
/* If executing the prompt fails, make sure we at least don't print any junk */
|
||||
|
@ -799,7 +798,7 @@ static void write_prompt()
|
|||
al_destroy( &prompt_list );
|
||||
al_init( &prompt_list );
|
||||
}
|
||||
is_interactive = was_interactive;
|
||||
proc_pop_interactive();
|
||||
}
|
||||
|
||||
data->prompt_width=calc_prompt_width( &prompt_list );
|
||||
|
@ -2967,10 +2966,8 @@ int reader_read( int fd )
|
|||
we need to preserve is_interactive, so we save the
|
||||
original state. We also update the signal handlers.
|
||||
*/
|
||||
int shell_was_interactive = is_interactive;
|
||||
|
||||
is_interactive = ((fd == 0) && isatty(STDIN_FILENO));
|
||||
signal_set_handlers();
|
||||
proc_push_interactive( ((fd == 0) && isatty(STDIN_FILENO)));
|
||||
|
||||
res= is_interactive?read_i():read_ni( fd );
|
||||
|
||||
|
@ -2982,7 +2979,6 @@ int reader_read( int fd )
|
|||
data->end_loop = 0;
|
||||
end_loop = 0;
|
||||
|
||||
is_interactive = shell_was_interactive;
|
||||
signal_set_handlers();
|
||||
proc_pop_interactive();
|
||||
return res;
|
||||
}
|
||||
|
|
5
signal.c
5
signal.c
|
@ -387,7 +387,6 @@ static void handle_winch( int sig, siginfo_t *info, void *context )
|
|||
static void handle_int( int sig, siginfo_t *info, void *context )
|
||||
{
|
||||
reader_handle_int( sig );
|
||||
|
||||
default_handler( sig, info, context);
|
||||
}
|
||||
|
||||
|
@ -422,6 +421,10 @@ void signal_reset_handlers()
|
|||
void signal_set_handlers()
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
if( is_interactive == -1 )
|
||||
return;
|
||||
|
||||
sigemptyset( & act.sa_mask );
|
||||
act.sa_flags=SA_SIGINFO;
|
||||
act.sa_sigaction = &default_handler;
|
||||
|
|
Loading…
Reference in a new issue