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:
axel 2006-10-30 07:09:11 +10:00
parent a6c00ca0d2
commit f83575f084
8 changed files with 79 additions and 29 deletions

View File

@ -74,7 +74,7 @@ extern wchar_t *program_name;
failiure, the current function is ended at once. The second failiure, the current function is ended at once. The second
parameter is the exit status of the current function on failiure. parameter is the exit status of the current function on failiure.
*/ */
#define CHECK( arg, retval ) \ #define CHECK( arg, retval ) \
if( !(arg) ) \ if( !(arg) ) \
{ \ { \
debug( 1, \ debug( 1, \
@ -85,18 +85,44 @@ extern wchar_t *program_name;
#arg, \ #arg, \
PACKAGE_BUGREPORT ); \ PACKAGE_BUGREPORT ); \
return retval; \ return retval; \
} \ }
/** /**
Exit program at once, leaving an error message about running out of memory 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); \ 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 Shorthand for wgettext call
*/ */

17
exec.c
View File

@ -682,12 +682,11 @@ void exec( job_t *j )
CHECK( j, ); CHECK( j, );
CHECK_BLOCK();
if( no_exec ) if( no_exec )
return; return;
sigemptyset( &chldset ); sigemptyset( &chldset );
sigaddset( &chldset, SIGCHLD ); sigaddset( &chldset, SIGCHLD );
@ -873,7 +872,17 @@ void exec( job_t *j )
{ {
case INTERNAL_FUNCTION: 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 ) if( def == 0 )
{ {
debug( 0, _( L"Unknown function '%ls'" ), p->argv[0] ); debug( 0, _( L"Unknown function '%ls'" ), p->argv[0] );

View File

@ -353,10 +353,6 @@ const wchar_t *function_get_definition_file( const wchar_t *argv )
CHECK( argv, 0 ); CHECK( argv, 0 );
if( is_autoload )
return 0;
load( argv );
data = (function_data_t *)hash_get( &function, argv ); data = (function_data_t *)hash_get( &function, argv );
if( data == 0 ) if( data == 0 )
return 0; return 0;
@ -371,10 +367,6 @@ int function_get_definition_offset( const wchar_t *argv )
CHECK( argv, -1 ); CHECK( argv, -1 );
if( is_autoload )
return -1;
load( argv );
data = (function_data_t *)hash_get( &function, argv ); data = (function_data_t *)hash_get( &function, argv );
if( data == 0 ) if( data == 0 )
return -1; return -1;

View File

@ -685,6 +685,8 @@ int parse_util_load( const wchar_t *cmd,
CHECK( path_var_name, 0 ); CHECK( path_var_name, 0 );
CHECK( cmd, 0 ); CHECK( cmd, 0 );
CHECK_BLOCK( 0 );
// debug( 0, L"Autoload %ls in %ls", cmd, path_var_name ); // debug( 0, L"Autoload %ls in %ls", cmd, path_var_name );
parse_util_autounload( path_var_name, cmd, on_load ); 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 ) 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); parse_util_load_reset( path_var_name, on_load);
reload = parse_util_load( cmd, path_var_name, on_load, reload ); reload = parse_util_load( cmd, path_var_name, on_load, reload );
return 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 ); res = parse_util_load_internal( cmd, on_load, reload, loaded, path_list );
/** autoload_t *loaded2 = (autoload_t *)hash_get( all_loaded, path_var_name );
Cleanup if( loaded2 == loaded )
*/ {
hash_remove( &loaded->is_loading, cmd, 0, 0 ); /**
Cleanup
*/
hash_remove( &loaded->is_loading, cmd, 0, 0 );
}
c2 = al_get_count( path_list ); c2 = al_get_count( path_list );
al_foreach( path_list, &free ); al_foreach( path_list, &free );

View File

@ -42,6 +42,7 @@ The fish parser. Contains functions for parsing code.
#include "halloc.h" #include "halloc.h"
#include "halloc_util.h" #include "halloc_util.h"
#include "path.h" #include "path.h"
#include "signal.h"
/** /**
Maximum number of block levels in code. This is not the same as 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; block_t *prev_block = current_block;
int prev_tokenizer_pos = current_tokenizer_pos; int prev_tokenizer_pos = current_tokenizer_pos;
current_tokenizer_pos = tok_get_pos( tok ); current_tokenizer_pos = tok_get_pos( tok );
while( al_get_count( args ) == 0 ) 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(); forbidden_function = al_new();
} }
CHECK_BLOCK( 1 );
forbid_count = al_get_count( forbidden_function ); forbid_count = al_get_count( forbidden_function );
block_io = io; block_io = io;

5
proc.c
View File

@ -858,7 +858,7 @@ void job_continue (job_t *j, int cont)
first_job = j; first_job = j;
job_set_flag( j, JOB_NOTIFIED, 0 ); job_set_flag( j, JOB_NOTIFIED, 0 );
debug( 4, debug( 3,
L"Continue job %d (%ls), %ls, %ls", L"Continue job %d (%ls), %ls, %ls",
j->job_id, j->job_id,
j->command, j->command,
@ -895,7 +895,7 @@ void job_continue (job_t *j, int cont)
} }
signal_unblock(); signal_unblock();
} }
/* /*
Send the job a continue signal, if necessary. Send the job a continue signal, if necessary.
*/ */
@ -931,7 +931,6 @@ void job_continue (job_t *j, int cont)
{ {
int quit = 0; int quit = 0;
// debug( 1, L"wait loop" );
/* /*
Wait for job to report. Looks a bit ugly because it has to Wait for job to report. Looks a bit ugly because it has to
handle the possibility that a signal is dispatched while handle the possibility that a signal is dispatched while

View File

@ -650,6 +650,7 @@ void signal_block()
} }
block_count++; block_count++;
// debug( 0, L"signal block level increased to %d", block_count );
} }
void signal_unblock() void signal_unblock()
@ -663,5 +664,11 @@ void signal_unblock()
sigfillset( &chldset ); sigfillset( &chldset );
sigprocmask(SIG_UNBLOCK, &chldset, 0); sigprocmask(SIG_UNBLOCK, &chldset, 0);
} }
// debug( 0, L"signal block level decreased to %d", block_count );
} }
int signal_is_blocked()
{
return !!block_count;
}

View File

@ -3,6 +3,8 @@
The library for various signal related issues The library for various signal related issues
*/ */
#ifndef FISH_SIGNALH
#define FISH_SIGNALH
/** /**
Get the integer signal value representing the specified signal, or Get the integer signal value representing the specified signal, or
@ -47,3 +49,10 @@ void signal_block();
Unblock all signals Unblock all signals
*/ */
void signal_unblock(); void signal_unblock();
/**
Returns true if signals are being blocked
*/
int signal_is_blocked();
#endif