mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-03-27 14:45:13 +08: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
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
|
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
17
exec.c
@ -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] );
|
||||||
|
@ -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;
|
||||||
|
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( 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 );
|
||||||
|
5
parser.c
5
parser.c
@ -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
5
proc.c
@ -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
|
||||||
|
9
signal.c
9
signal.c
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
9
signal.h
9
signal.h
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user