mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Make sure signals aren't blocked while autoloading, also add a few consistency checks to see that signals aren't blocked in critical places
darcs-hash:20061029210911-ac50b-50bec85c3d59d0332ba44f3ece1a012cdc3e8c4b.gz
This commit is contained in:
parent
a6c00ca0d2
commit
f83575f084
8 changed files with 79 additions and 29 deletions
38
common.h
38
common.h
|
@ -74,7 +74,7 @@ extern wchar_t *program_name;
|
|||
failiure, the current function is ended at once. The second
|
||||
parameter is the exit status of the current function on failiure.
|
||||
*/
|
||||
#define CHECK( arg, retval ) \
|
||||
#define CHECK( arg, retval ) \
|
||||
if( !(arg) ) \
|
||||
{ \
|
||||
debug( 1, \
|
||||
|
@ -85,18 +85,44 @@ extern wchar_t *program_name;
|
|||
#arg, \
|
||||
PACKAGE_BUGREPORT ); \
|
||||
return retval; \
|
||||
} \
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Exit program at once, leaving an error message about running out of memory
|
||||
*/
|
||||
#define DIE_MEM() \
|
||||
#define DIE_MEM() \
|
||||
{ \
|
||||
fwprintf( stderr, L"fish: Out of memory on line %d of file %s, shutting down fish\n", __LINE__, __FILE__ ); \
|
||||
fwprintf( stderr, \
|
||||
L"fish: Out of memory on line %d of file %s, shutting down fish\n", \
|
||||
__LINE__, \
|
||||
__FILE__ ); \
|
||||
exit(1); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
Cause fish to crash. This should only be usd for debugging.
|
||||
*/
|
||||
#define CRASH() \
|
||||
{ \
|
||||
int *n = 0; \
|
||||
*n = 1; \
|
||||
}
|
||||
|
||||
/**
|
||||
Check if signals are blocked
|
||||
*/
|
||||
#define CHECK_BLOCK( retval ) \
|
||||
if( signal_is_blocked() ) \
|
||||
{ \
|
||||
debug( 0, \
|
||||
L"function %s called while blocking signals. " \
|
||||
L"This is a bug. " \
|
||||
L"If you can reproduce it, please send a bug report to %s.", \
|
||||
__func__, \
|
||||
PACKAGE_BUGREPORT ); \
|
||||
return retval; \
|
||||
}
|
||||
|
||||
/**
|
||||
Shorthand for wgettext call
|
||||
*/
|
||||
|
|
17
exec.c
17
exec.c
|
@ -682,12 +682,11 @@ void exec( job_t *j )
|
|||
|
||||
|
||||
CHECK( j, );
|
||||
|
||||
CHECK_BLOCK();
|
||||
|
||||
if( no_exec )
|
||||
return;
|
||||
|
||||
|
||||
|
||||
sigemptyset( &chldset );
|
||||
sigaddset( &chldset, SIGCHLD );
|
||||
|
||||
|
@ -873,7 +872,17 @@ void exec( job_t *j )
|
|||
{
|
||||
case INTERNAL_FUNCTION:
|
||||
{
|
||||
wchar_t * def = halloc_register( j, wcsdup( function_get_definition( p->argv[0] )));
|
||||
const wchar_t * orig_def;
|
||||
wchar_t * def=0;
|
||||
|
||||
signal_unblock();
|
||||
orig_def = function_get_definition( p->argv[0] );
|
||||
signal_block();
|
||||
|
||||
if( orig_def )
|
||||
{
|
||||
def = halloc_register( j, wcsdup(orig_def) );
|
||||
}
|
||||
if( def == 0 )
|
||||
{
|
||||
debug( 0, _( L"Unknown function '%ls'" ), p->argv[0] );
|
||||
|
|
|
@ -353,10 +353,6 @@ const wchar_t *function_get_definition_file( const wchar_t *argv )
|
|||
|
||||
CHECK( argv, 0 );
|
||||
|
||||
if( is_autoload )
|
||||
return 0;
|
||||
|
||||
load( argv );
|
||||
data = (function_data_t *)hash_get( &function, argv );
|
||||
if( data == 0 )
|
||||
return 0;
|
||||
|
@ -371,10 +367,6 @@ int function_get_definition_offset( const wchar_t *argv )
|
|||
|
||||
CHECK( argv, -1 );
|
||||
|
||||
if( is_autoload )
|
||||
return -1;
|
||||
|
||||
load( argv );
|
||||
data = (function_data_t *)hash_get( &function, argv );
|
||||
if( data == 0 )
|
||||
return -1;
|
||||
|
|
17
parse_util.c
17
parse_util.c
|
@ -685,6 +685,8 @@ int parse_util_load( const wchar_t *cmd,
|
|||
CHECK( path_var_name, 0 );
|
||||
CHECK( cmd, 0 );
|
||||
|
||||
CHECK_BLOCK( 0 );
|
||||
|
||||
// debug( 0, L"Autoload %ls in %ls", cmd, path_var_name );
|
||||
|
||||
parse_util_autounload( path_var_name, cmd, on_load );
|
||||
|
@ -724,7 +726,6 @@ int parse_util_load( const wchar_t *cmd,
|
|||
*/
|
||||
if( wcscmp( path_var, loaded->old_path ) != 0 )
|
||||
{
|
||||
debug( 0, L"path change, new path is %ls", path_var );
|
||||
parse_util_load_reset( path_var_name, on_load);
|
||||
reload = parse_util_load( cmd, path_var_name, on_load, reload );
|
||||
return reload;
|
||||
|
@ -779,11 +780,15 @@ int parse_util_load( const wchar_t *cmd,
|
|||
|
||||
res = parse_util_load_internal( cmd, on_load, reload, loaded, path_list );
|
||||
|
||||
/**
|
||||
Cleanup
|
||||
*/
|
||||
hash_remove( &loaded->is_loading, cmd, 0, 0 );
|
||||
|
||||
autoload_t *loaded2 = (autoload_t *)hash_get( all_loaded, path_var_name );
|
||||
if( loaded2 == loaded )
|
||||
{
|
||||
/**
|
||||
Cleanup
|
||||
*/
|
||||
hash_remove( &loaded->is_loading, cmd, 0, 0 );
|
||||
}
|
||||
|
||||
c2 = al_get_count( path_list );
|
||||
|
||||
al_foreach( path_list, &free );
|
||||
|
|
5
parser.c
5
parser.c
|
@ -42,6 +42,7 @@ The fish parser. Contains functions for parsing code.
|
|||
#include "halloc.h"
|
||||
#include "halloc_util.h"
|
||||
#include "path.h"
|
||||
#include "signal.h"
|
||||
|
||||
/**
|
||||
Maximum number of block levels in code. This is not the same as
|
||||
|
@ -1699,7 +1700,7 @@ static int parse_job( process_t *p,
|
|||
|
||||
block_t *prev_block = current_block;
|
||||
int prev_tokenizer_pos = current_tokenizer_pos;
|
||||
|
||||
|
||||
current_tokenizer_pos = tok_get_pos( tok );
|
||||
|
||||
while( al_get_count( args ) == 0 )
|
||||
|
@ -2482,6 +2483,8 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
|
|||
forbidden_function = al_new();
|
||||
}
|
||||
|
||||
CHECK_BLOCK( 1 );
|
||||
|
||||
forbid_count = al_get_count( forbidden_function );
|
||||
|
||||
block_io = io;
|
||||
|
|
5
proc.c
5
proc.c
|
@ -858,7 +858,7 @@ void job_continue (job_t *j, int cont)
|
|||
first_job = j;
|
||||
job_set_flag( j, JOB_NOTIFIED, 0 );
|
||||
|
||||
debug( 4,
|
||||
debug( 3,
|
||||
L"Continue job %d (%ls), %ls, %ls",
|
||||
j->job_id,
|
||||
j->command,
|
||||
|
@ -895,7 +895,7 @@ void job_continue (job_t *j, int cont)
|
|||
}
|
||||
signal_unblock();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Send the job a continue signal, if necessary.
|
||||
*/
|
||||
|
@ -931,7 +931,6 @@ void job_continue (job_t *j, int cont)
|
|||
{
|
||||
int quit = 0;
|
||||
|
||||
// debug( 1, L"wait loop" );
|
||||
/*
|
||||
Wait for job to report. Looks a bit ugly because it has to
|
||||
handle the possibility that a signal is dispatched while
|
||||
|
|
9
signal.c
9
signal.c
|
@ -650,6 +650,7 @@ void signal_block()
|
|||
}
|
||||
|
||||
block_count++;
|
||||
// debug( 0, L"signal block level increased to %d", block_count );
|
||||
}
|
||||
|
||||
void signal_unblock()
|
||||
|
@ -663,5 +664,11 @@ void signal_unblock()
|
|||
sigfillset( &chldset );
|
||||
sigprocmask(SIG_UNBLOCK, &chldset, 0);
|
||||
}
|
||||
|
||||
// debug( 0, L"signal block level decreased to %d", block_count );
|
||||
}
|
||||
|
||||
int signal_is_blocked()
|
||||
{
|
||||
return !!block_count;
|
||||
}
|
||||
|
||||
|
|
9
signal.h
9
signal.h
|
@ -3,6 +3,8 @@
|
|||
The library for various signal related issues
|
||||
|
||||
*/
|
||||
#ifndef FISH_SIGNALH
|
||||
#define FISH_SIGNALH
|
||||
|
||||
/**
|
||||
Get the integer signal value representing the specified signal, or
|
||||
|
@ -47,3 +49,10 @@ void signal_block();
|
|||
Unblock all signals
|
||||
*/
|
||||
void signal_unblock();
|
||||
|
||||
/**
|
||||
Returns true if signals are being blocked
|
||||
*/
|
||||
int signal_is_blocked();
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue