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
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
View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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