aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--common.h38
-rw-r--r--exec.c17
-rw-r--r--function.c8
-rw-r--r--parse_util.c17
-rw-r--r--parser.c5
-rw-r--r--proc.c5
-rw-r--r--signal.c7
-rw-r--r--signal.h9
8 files changed, 78 insertions, 28 deletions
diff --git a/common.h b/common.h
index b787fbe9..99c5671e 100644
--- a/common.h
+++ b/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,19 +85,45 @@ 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
*/
#define _(wstr) wgettext(wstr)
diff --git a/exec.c b/exec.c
index 3b89a3bc..dd8ee76b 100644
--- a/exec.c
+++ b/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] );
diff --git a/function.c b/function.c
index 2e138561..54a171ed 100644
--- a/function.c
+++ b/function.c
@@ -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;
diff --git a/parse_util.c b/parse_util.c
index af4b20c5..3e939bd9 100644
--- a/parse_util.c
+++ b/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 );
diff --git a/parser.c b/parser.c
index e5c0c1fd..c9236754 100644
--- a/parser.c
+++ b/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;
diff --git a/proc.c b/proc.c
index e13f8a7c..72a5d12c 100644
--- a/proc.c
+++ b/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
diff --git a/signal.c b/signal.c
index 18fc3eec..45630208 100644
--- a/signal.c
+++ b/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;
}
+
diff --git a/signal.h b/signal.h
index 5fb4a897..91bddc92 100644
--- a/signal.h
+++ b/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