aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile.in20
-rw-r--r--builtin.c24
-rw-r--r--common.c52
-rw-r--r--common.h19
-rw-r--r--complete.c46
-rw-r--r--event.c15
-rw-r--r--exec.c1
-rw-r--r--expand.c33
-rw-r--r--expand.h5
-rw-r--r--fish_pager.c7
-rw-r--r--halloc.c36
-rw-r--r--halloc.h33
-rw-r--r--halloc_util.c69
-rw-r--r--halloc_util.h29
-rw-r--r--highlight.c4
-rw-r--r--history.c6
-rw-r--r--input.c5
-rw-r--r--main.c15
-rw-r--r--output.c13
-rw-r--r--output.h10
-rw-r--r--parse_util.c67
-rw-r--r--parse_util.h11
-rw-r--r--parser.c132
-rw-r--r--proc.c1
-rw-r--r--signal.c20
-rw-r--r--translate.c47
-rw-r--r--translate.h8
27 files changed, 379 insertions, 349 deletions
diff --git a/Makefile.in b/Makefile.in
index fad72da0..c57da135 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -59,14 +59,16 @@ INIT_DIR_INSTALL = init/fish_interactive.fish init/fish_function.fish init/fish_
# Set to 1 if we have gettext
HAVE_GETTEXT=@HAVE_GETTEXT@
+CORE_OBJS := util.o common.o halloc.o halloc_util.o
+
# All objects used by fish, that are compiled from an ordinary .c file
# using an ordinary .h file.
-COMMON_OBJS := function.o builtin.o common.o complete.o env.o exec.o \
+COMMON_OBJS := function.o builtin.o complete.o env.o exec.o \
expand.o highlight.o history.o kill.o parser.o proc.o reader.o \
- sanity.o tokenizer.o util.o wildcard.o wgetopt.o wutil.o input.o \
+ sanity.o tokenizer.o wildcard.o wgetopt.o wutil.o input.o \
output.o intern.o env_universal.o env_universal_common.o \
input_common.o event.o signal.o io.o translate.o parse_util.o \
- halloc.o
+ $(CORE_OBJS)
# builtin_help.h exists, but builtin_help.c is autogenerated
COMMON_OBJS_WITH_HEADER := builtin_help.o
@@ -80,21 +82,21 @@ FISH_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
$(COMMON_OBJS_WITH_HEADER) main.o
# All objects that the system needs to build fish_pager
-FISH_PAGER_OBJS := fish_pager.o common.o output.o util.o wutil.o \
+FISH_PAGER_OBJS := fish_pager.o output.o wutil.o \
tokenizer.o input_common.o env_universal.o env_universal_common.o \
- translate.o halloc.o
+ translate.o $(CORE_OBJS)
# All objects that the system needs to build fish_tests
FISH_TESTS_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
$(COMMON_OBJS_WITH_HEADER) fish_tests.o
# All objects that the system needs to build fishd
-FISHD_OBJS := fishd.o env_universal_common.o common.o util.o wutil.o \
- doc_src/fishd.o halloc.o
+FISHD_OBJS := fishd.o env_universal_common.o wutil.o \
+ doc_src/fishd.o $(CORE_OBJS)
# All objects needed to build mimedb
-MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
- xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o halloc.o
+MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
+ xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o
#
# Files containing documentation for builtins. Should be listed
diff --git a/builtin.c b/builtin.c
index b049d3c1..cb3d9fac 100644
--- a/builtin.c
+++ b/builtin.c
@@ -60,6 +60,7 @@
#include "signal.h"
#include "translate.h"
#include "halloc.h"
+#include "halloc_util.h"
/**
The default prompt for the read command
@@ -496,7 +497,7 @@ static int builtin_builtin( wchar_t **argv )
al_init( &names );
builtin_get_names( &names );
- names_arr = list_to_char_arr( 0, &names );
+ names_arr = list_to_char_arr( &names );
qsort( names_arr,
al_get_count( &names ),
sizeof(wchar_t *),
@@ -511,7 +512,7 @@ static int builtin_builtin( wchar_t **argv )
L"\n",
(void *)0 );
}
- halloc_free( names_arr );
+ free( names_arr );
al_destroy( &names );
}
return 0;
@@ -813,7 +814,7 @@ static int builtin_functions( wchar_t **argv )
al_init( &names );
function_get_names( &names, show_hidden );
- names_arr = list_to_char_arr( 0, &names );
+ names_arr = list_to_char_arr( &names );
qsort( names_arr,
al_get_count( &names ),
sizeof(wchar_t *),
@@ -845,7 +846,7 @@ static int builtin_functions( wchar_t **argv )
}
}
- halloc_free( names_arr );
+ free( names_arr );
al_destroy( &names );
return 0;
}
@@ -858,7 +859,7 @@ static int builtin_functions( wchar_t **argv )
sb_append( sb_out, _( L"Current function definitions are:\n\n" ) );
al_init( &names );
function_get_names( &names, show_hidden );
- names_arr = list_to_char_arr( 0, &names );
+ names_arr = list_to_char_arr( &names );
qsort( names_arr,
al_get_count( &names ),
sizeof(wchar_t *),
@@ -867,7 +868,7 @@ static int builtin_functions( wchar_t **argv )
{
functions_def( names_arr[i] );
}
- halloc_free( names_arr );
+ free( names_arr );
al_destroy( &names );
break;
}
@@ -924,8 +925,7 @@ static int builtin_function( wchar_t **argv )
woptind=0;
parser_push_block( FUNCTION_DEF );
- events=halloc( current_block, sizeof(array_list_t ) );
- al_init( events );
+ events=al_halloc( current_block );
const static struct woption
long_options[] =
@@ -1160,8 +1160,6 @@ static int builtin_function( wchar_t **argv )
}
}
- halloc_register( current_block, events->arr );
-
if( res )
{
int i;
@@ -1176,7 +1174,7 @@ static int builtin_function( wchar_t **argv )
al_init( &names );
function_get_names( &names, 0 );
- names_arr = list_to_char_arr( 0, &names );
+ names_arr = list_to_char_arr( &names );
qsort( names_arr,
al_get_count( &names ),
sizeof(wchar_t *),
@@ -1194,7 +1192,7 @@ static int builtin_function( wchar_t **argv )
sb_append2( sb_err,
nxt, L" ", (void *)0 );
}
- halloc_free( names_arr );
+ free( names_arr );
al_destroy( &names );
sb_append( sb_err, L"\n" );
@@ -1207,7 +1205,7 @@ static int builtin_function( wchar_t **argv )
current_block->param2.function_description=desc?halloc_register( current_block, wcsdup(desc)):0;
current_block->param3.function_is_binding = is_binding;
current_block->param4.function_events = events;
-
+
for( i=0; i<al_get_count( events ); i++ )
{
event_t *e = (event_t *)al_get( events, i );
diff --git a/common.c b/common.c
index 751c1ffd..e743f632 100644
--- a/common.c
+++ b/common.c
@@ -20,7 +20,6 @@ parts of fish.
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
-#include <signal.h>
#include <locale.h>
#include <time.h>
#include <sys/time.h>
@@ -58,7 +57,6 @@ parts of fish.
#include "proc.h"
#include "wildcard.h"
#include "parser.h"
-#include "halloc.h"
/**
The maximum number of minor errors to report. Further errors will be omitted.
@@ -95,20 +93,14 @@ int debug_level=1;
*/
static struct winsize termsize;
-
-/**
- Number of nested calls to the block function. Unblock when this reaches 0.
-*/
-static int block_count=0;
-
/**
String buffer used by the wsetlocale function
*/
static string_buffer_t *setlocale_buff=0;
-
void common_destroy()
{
+
if( setlocale_buff )
{
sb_destroy( setlocale_buff );
@@ -116,9 +108,13 @@ void common_destroy()
}
}
-wchar_t **list_to_char_arr( void *context, array_list_t *l )
+void common_init()
{
- wchar_t ** res = halloc( context, sizeof(wchar_t *)*(al_get_count( l )+1) );
+}
+
+wchar_t **list_to_char_arr( array_list_t *l )
+{
+ wchar_t ** res = malloc( sizeof(wchar_t *)*(al_get_count( l )+1) );
int i;
if( res == 0 )
{
@@ -127,40 +123,11 @@ wchar_t **list_to_char_arr( void *context, array_list_t *l )
for( i=0; i<al_get_count( l ); i++ )
{
res[i] = (wchar_t *)al_get(l,i);
- if( context )
- halloc_register( context, res[i] );
}
res[i]='\0';
return res;
}
-void block()
-{
- block_count++;
- if( block_count == 1 )
- {
- sigset_t chldset;
- sigemptyset( &chldset );
- sigaddset( &chldset, SIGCHLD );
- sigprocmask(SIG_BLOCK, &chldset, 0);
- }
-}
-
-
-void unblock()
-{
- block_count--;
- if( block_count == 0 )
- {
- sigset_t chldset;
- sigemptyset( &chldset );
- sigaddset( &chldset, SIGCHLD );
- sigprocmask(SIG_UNBLOCK, &chldset, 0);
- }
-}
-
-
-
int fgetws2( wchar_t **b, int *len, FILE *f )
{
int i=0;
@@ -174,8 +141,6 @@ int fgetws2( wchar_t **b, int *len, FILE *f )
watching for EINTR errors, bytes are lost.
*/
- block();
-
while( 1 )
{
/* Reallocate the buffer if necessary */
@@ -214,8 +179,6 @@ int fgetws2( wchar_t **b, int *len, FILE *f )
case L'\n':
case L'\0':
buff[i]=L'\0';
- unblock();
-
return i;
/* Ignore carriage returns */
case L'\r':
@@ -228,7 +191,6 @@ int fgetws2( wchar_t **b, int *len, FILE *f )
}
- unblock();
}
diff --git a/common.h b/common.h
index f18f391d..8ab2ba9d 100644
--- a/common.h
+++ b/common.h
@@ -88,7 +88,7 @@ extern wchar_t *program_name;
is not noll, all elements of the \c array_list_t are also
registered to \c context using \c halloc_register().
*/
-wchar_t **list_to_char_arr( void *context, array_list_t *l );
+wchar_t **list_to_char_arr( array_list_t *l );
/**
Read a line from the stream f into the buffer buff of length len. If
@@ -236,7 +236,12 @@ int writeb( tputs_arg_t b );
void die_mem();
/**
- Clean up
+ Create global_context using halloc
+*/
+void common_init();
+
+/**
+ Free global_context using halloc_free
*/
void common_destroy();
@@ -283,16 +288,6 @@ wchar_t *unescape( const wchar_t * in,
int escape_special );
/**
- Block SIGCHLD. Calls to block/unblock may be nested, and only once the nest count reaches zero wiull the block be removed.
-*/
-void block();
-
-/**
- undo call to block().
-*/
-void unblock();
-
-/**
Attempt to acquire a lock based on a lockfile, waiting LOCKPOLLINTERVAL
milliseconds between polls and timing out after timeout seconds,
thereafter forcibly attempting to obtain the lock if force is non-zero.
diff --git a/complete.c b/complete.c
index c35066b7..a2a73233 100644
--- a/complete.c
+++ b/complete.c
@@ -38,7 +38,7 @@
#include "intern.h"
#include "translate.h"
#include "parse_util.h"
-
+#include "halloc_util.h"
#include "wutil.h"
@@ -222,10 +222,6 @@ static hash_table_t *condition_cache=0;
static string_buffer_t *get_desc_buff=0;
-void complete_init()
-{
-}
-
/**
This command clears the cache of condition tests created by \c condition_test().
*/
@@ -322,6 +318,10 @@ static void clear_hash_entry( const void *key, const void *data )
free( (void *)data );
}
+void complete_init()
+{
+}
+
void complete_destroy()
{
complete_entry *i=first_entry, *prev;
@@ -341,14 +341,6 @@ void complete_destroy()
free( suffix_hash );
suffix_hash=0;
}
-
- if( get_desc_buff )
- {
- sb_destroy( get_desc_buff );
- free( get_desc_buff );
- get_desc_buff = 0;
- }
-
}
/**
@@ -885,14 +877,13 @@ const wchar_t *complete_get_desc( const wchar_t *filename )
if( !get_desc_buff )
{
- get_desc_buff = malloc(sizeof(string_buffer_t) );
- sb_init( get_desc_buff );
+ get_desc_buff = sb_halloc( global_context);
}
else
{
sb_clear( get_desc_buff );
}
-
+
if( lwstat( filename, &buf )==0)
{
if( S_ISCHR(buf.st_mode) )
@@ -1005,7 +996,8 @@ static void copy_strings_with_prefix( array_list_t *comp_out,
int i;
wchar_t *wc;
- wc = expand_one( wcsdup(wc_escaped), EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_WILDCARDS);
+ wc = expand_one( 0,
+ wcsdup(wc_escaped), EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_WILDCARDS);
if(!wc)
return;
@@ -1201,7 +1193,8 @@ static void complete_cmd( const wchar_t *cmd,
array_list_t tmp;
al_init( &tmp );
- if( expand_string( wcsdup(cmd),
+ if( expand_string( 0,
+ wcsdup(cmd),
comp,
ACCEPT_INCOMPLETE | EXECUTABLES_ONLY ) != EXPAND_ERROR )
{
@@ -1227,9 +1220,10 @@ static void complete_cmd( const wchar_t *cmd,
al_init( &tmp );
- if( expand_string( nxt_completion,
- &tmp,
- ACCEPT_INCOMPLETE |
+ if( expand_string( 0,
+ nxt_completion,
+ &tmp,
+ ACCEPT_INCOMPLETE |
EXECUTABLES_ONLY ) != EXPAND_ERROR )
{
for( i=0; i<al_get_count(&tmp); i++ )
@@ -1285,8 +1279,9 @@ static void complete_cmd( const wchar_t *cmd,
al_init( &tmp );
- if( expand_string( nxt_completion,
- &tmp,
+ if( expand_string( 0,
+ nxt_completion,
+ &tmp,
ACCEPT_INCOMPLETE | DIRECTORIES_ONLY ) != EXPAND_ERROR )
{
@@ -1672,7 +1667,10 @@ static void complete_param_expand( wchar_t *str,
comp_str,
do_file?L"0":L"EXPAND_SKIP_WILDCARDS" );
- expand_string( wcsdup(comp_str), comp_out, EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | (do_file?0:EXPAND_SKIP_WILDCARDS) );
+ expand_string( 0,
+ wcsdup(comp_str),
+ comp_out,
+ EXPAND_SKIP_SUBSHELL | ACCEPT_INCOMPLETE | (do_file?0:EXPAND_SKIP_WILDCARDS) );
}
/**
diff --git a/event.c b/event.c
index b4850e41..ca87b33c 100644
--- a/event.c
+++ b/event.c
@@ -21,6 +21,7 @@
#include "event.h"
#include "signal.h"
#include "translate.h"
+#include "halloc_util.h"
/**
Number of signals that can be queued before an overflow occurs
@@ -194,10 +195,7 @@ const wchar_t *event_get_desc( event_t *e )
{
if( !get_desc_buff )
{
- get_desc_buff=malloc(sizeof(string_buffer_t) );
- if( !get_desc_buff )
- die_mem();
- sb_init( get_desc_buff );
+ get_desc_buff=sb_halloc( global_context );
}
else
{
@@ -255,7 +253,7 @@ void event_add_handler( event_t *event )
e = event_copy( event, 0 );
if( !events )
- events = al_new();
+ events = al_new();
if( e->type == EVENT_SIGNAL )
{
@@ -644,13 +642,6 @@ void event_destroy()
free( killme );
killme=0;
}
-
- if( get_desc_buff )
- {
- sb_destroy( get_desc_buff );
- free( get_desc_buff );
- }
-
}
void event_free( event_t *e )
diff --git a/exec.c b/exec.c
index 8e8ef1a8..e004d17f 100644
--- a/exec.c
+++ b/exec.c
@@ -38,6 +38,7 @@
#include "env_universal.h"
#include "translate.h"
#include "halloc.h"
+#include "halloc_util.h"
/**
Prototype for the getpgid library function. The prototype for this
diff --git a/expand.c b/expand.c
index 65450959..534997a7 100644
--- a/expand.c
+++ b/expand.c
@@ -36,6 +36,7 @@ parameter expansion.
#include "expand.h"
#include "wildcard.h"
#include "exec.h"
+#include "signal.h"
#include "tokenizer.h"
#include "complete.h"
#include "translate.h"
@@ -557,8 +558,10 @@ static int find_process( const wchar_t *proc,
continue;
}
+ signal_block();
fgetws2( &cmd, &sz, cmdfile );
-
+ signal_unblock();
+
fclose( cmdfile );
}
else
@@ -903,9 +906,9 @@ static int expand_variables( wchar_t *in, array_list_t *out )
{
string_buffer_t res;
sb_init( &res );
-
+
in[i]=0;
-
+
sb_append( &res, in );
sb_append_char( &res, INTERNAL_SEPARATOR );
@@ -1393,7 +1396,8 @@ static void remove_internal_separator( const void *s, int conv )
/**
The real expansion function. expand_one is just a wrapper around this one.
*/
-int expand_string( wchar_t *str,
+int expand_string( void *context,
+ wchar_t *str,
array_list_t *end_out,
int flags )
{
@@ -1403,12 +1407,14 @@ int expand_string( wchar_t *str,
int i;
int subshell_ok = 1;
int res = EXPAND_OK;
+ int start_count = al_get_count( end_out );
// debug( 1, L"Expand %ls", str );
if( (!(flags & ACCEPT_INCOMPLETE)) && is_clean( str ) )
{
+ halloc_register( context, str );
al_push( end_out, str );
return EXPAND_OK;
}
@@ -1597,22 +1603,33 @@ int expand_string( wchar_t *str,
al_destroy( out );
}
+ if( context )
+ {
+ for( i=start_count; i<al_get_count( end_out ); i++ )
+ {
+ halloc_register( context, al_get( end_out, i ) );
+ }
+ }
+
return res;
}
-wchar_t *expand_one( wchar_t *string, int flags )
+wchar_t *expand_one( void *context, wchar_t *string, int flags )
{
array_list_t l;
int res;
wchar_t *one;
if( (!(flags & ACCEPT_INCOMPLETE)) && is_clean( string ) )
+ {
+ halloc_register( context, string );
return string;
-
+ }
+
al_init( &l );
- res = expand_string( string, &l, flags );
+ res = expand_string( 0, string, &l, flags );
if( !res )
{
one = 0;
@@ -1632,6 +1649,8 @@ wchar_t *expand_one( wchar_t *string, int flags )
al_foreach( &l, (void(*)(const void *))&free );
al_destroy( &l );
+
+ halloc_register( context, string );
return one;
}
diff --git a/expand.h b/expand.h
index 61331875..24337dcd 100644
--- a/expand.h
+++ b/expand.h
@@ -130,7 +130,7 @@ enum
\param out The list to which the result will be appended.
\return One of EXPAND_OK, EXPAND_ERROR, EXPAND_WILDCARD_MATCH and EXPAND_WILDCARD_NO_MATCH
*/
-int expand_string( wchar_t *in, array_list_t *out, int flag );
+int expand_string( void *context, wchar_t *in, array_list_t *out, int flag );
/**
expand_one is identical to expand_string, except it will fail if in
@@ -141,14 +141,13 @@ int expand_string( wchar_t *in, array_list_t *out, int flag );
\param flag Specifies if any expansion pass should be skipped. Legal values are any combination of EXPAND_SKIP_SUBSHELL EXPAND_SKIP_VARIABLES and EXPAND_SKIP_WILDCARDS
\return The expanded parameter, or 0 on failiure
*/
-wchar_t *expand_one( wchar_t *in, int flag );
+wchar_t *expand_one( void *context, wchar_t *in, int flag );
/**
Convert the variable value to a human readable form, i.e. escape things, handle arrays, etc. Suitable for pretty-printing.
*/
wchar_t *expand_escape_variable( const wchar_t *in );
-
/**
Perform tilde expansion and nothing else on the specified string.
diff --git a/fish_pager.c b/fish_pager.c
index 2aefdb97..a1a30534 100644
--- a/fish_pager.c
+++ b/fish_pager.c
@@ -887,7 +887,7 @@ static void init()
*/
sb_init( &out_buff );
- output_init();
+ halloc_util_init();
env_universal_init( 0, 0, 0, 0);
input_common_init( &interrupt_handler );
@@ -914,6 +914,9 @@ static void init()
pager_modes.c_cc[VMIN]=1;
pager_modes.c_cc[VTIME]=0;
+ /*
+
+ */
if( tcsetattr(0,TCSANOW,&pager_modes)) /* set the new modes */
{
wperror(L"tcsetattr");
@@ -932,7 +935,7 @@ void destroy()
{
env_universal_destroy();
input_common_destroy();
- output_destroy();
+ halloc_util_destroy();
del_curterm( cur_term );
sb_destroy( &out_buff );
fclose( out_file );
diff --git a/halloc.c b/halloc.c
index 741f4862..95000d02 100644
--- a/halloc.c
+++ b/halloc.c
@@ -18,7 +18,6 @@
typedef struct halloc
{
array_list_t children;
- array_list_t hchildren;
long long data[0];
}
halloc_t;
@@ -30,49 +29,52 @@ static halloc_t *halloc_from_data( void *data )
void *halloc( void *context, size_t size )
-{
-
+{
halloc_t *me, *parent;
me = (halloc_t *)calloc( 1, sizeof(halloc_t) + size );
-
+
if( !me )
return 0;
-
+
al_init( &me->children );
-
+
if( context )
{
parent = halloc_from_data( context );
- al_push( &parent->hchildren, &me->data );
+ al_push( &parent->children, &halloc_free );
+ al_push( &parent->children, &me->data );
}
-
+
return &me->data;
}
-void *halloc_register( void *context, void *data )
+void halloc_register_function( void *context, void (*func)(void *), void *data )
{
halloc_t *me;
if( !context )
- return data;
+ return;
me = halloc_from_data( context );
+ al_push( &me->children, func );
al_push( &me->children, data );
- return data;
}
-
void halloc_free( void *context )
{
halloc_t *me;
+ int i;
+
if( !context )
return;
-
+
me = halloc_from_data( context );
- al_foreach( &me->hchildren, (void (*)(const void *))&halloc_free );
- al_foreach( &me->children, (void (*)(const void *))&free );
+ for( i=0; i<al_get_count(&me->children); i+=2 )
+ {
+ void (*func)(void *) = (void (*)(void *))al_get( &me->children, i );
+ void * data = (void *)al_get( &me->children, i+1 );
+ func( data );
+ }
al_destroy( &me->children );
- al_destroy( &me->hchildren );
free(me);
}
-
diff --git a/halloc.h b/halloc.h
index 08931890..6dfdb4e2 100644
--- a/halloc.h
+++ b/halloc.h
@@ -6,30 +6,33 @@
*/
+#ifndef FISH_HALLOC_H
+#define FISH_HALLOC_H
+
/**
- Allocate new memory using specified parent memory context. If \c
- context is null, a new root context is created. Context _must_ be
- either 0 or the result of a previous call to halloc.
+ Allocate new memory using specified parent memory context. Context
+ _must_ be either 0 or the result of a previous call to halloc.
- If \c context is null, the resulting block must be freed with a
- call to halloc_free().
+ If \c context is null, the resulting block is a root context, and
+ must be freed with a call to halloc_free().
- If \c context is not null, the resulting memory block must never be
- explicitly freed, it will be automatically freed whenever the
- parent context is freed.
+ If \c context is not null, the resulting memory block is a child
+ context, and must never be explicitly freed, it will be
+ automatically freed whenever the parent context is freed.
*/
void *halloc( void *context, size_t size );
/**
+ Make the specified function run whenever context is free'd, using data as argument.
+*/
+void halloc_register_function( void *context, void (*func)(void *), void *data );
+
+/**
Free memory context and all children contexts. Only root contexts
may be freed explicitly.
*/
void halloc_free( void *context );
-/**
- Free the memory pointed to by \c data when the memory pointed to by
- \c context is free:d. Note that this will _not_ turn the specified
- memory area into a valid halloc context. Only memory areas created
- using a call to halloc() can be used as a context.
-*/
-void *halloc_register( void *context, void *data );
+
+#endif
+
diff --git a/halloc_util.c b/halloc_util.c
new file mode 100644
index 00000000..bc575f7e
--- /dev/null
+++ b/halloc_util.c
@@ -0,0 +1,69 @@
+/** \file halloc.c
+
+ A hierarchical memory allocation system. Works just like talloc
+ used in Samba, except that an arbitrary block allocated with
+ malloc() can be registered to be freed by halloc_free.
+
+*/
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "common.h"
+#include "halloc.h"
+
+void *global_context=0;
+
+void halloc_util_init()
+{
+ global_context = halloc( 0, 0 );
+}
+
+void halloc_util_destroy()
+{
+ halloc_free( global_context );
+}
+
+array_list_t *al_halloc( void *context )
+{
+ array_list_t *res = halloc( context, sizeof( array_list_t ) );
+ if( !res )
+ die_mem();
+ al_init( res );
+ halloc_register_function( res, (void (*)(void *)) &al_destroy, res );
+ return res;
+}
+
+string_buffer_t *sb_halloc( void *context )
+{
+ string_buffer_t *res = halloc( context, sizeof( string_buffer_t ) );
+ if( !res )
+ die_mem();
+ sb_init( res );
+ halloc_register_function( res, (void (*)(void *)) &sb_destroy, res );
+ return res;
+}
+
+static void halloc_passthrough( void *f )
+{
+ void (*func)() = (void (*)() )f;
+ func();
+}
+
+void halloc_register_function_void( void *context, void (*func)() )
+{
+ halloc_register_function( context, &halloc_passthrough, (void *)func );
+}
+
+void *halloc_register( void *context, void *data )
+{
+ if( !data )
+ return 0;
+
+ halloc_register_function( context, &free, data );
+ return data;
+}
+
diff --git a/halloc_util.h b/halloc_util.h
new file mode 100644
index 00000000..c58dff20
--- /dev/null
+++ b/halloc_util.h
@@ -0,0 +1,29 @@
+/**
+ \file halloc_util.h
+
+ Various halloc-related utility functions.
+*/
+
+#ifndef FISH_HALLOC_UTIL_H
+#define FISH_HALLOC_UTIL_H
+
+extern void *global_context;
+
+void halloc_util_init();
+
+void halloc_util_destroy();
+
+
+array_list_t *al_halloc( void *context );
+
+string_buffer_t *sb_halloc( void *context );
+
+void halloc_register_function_void( void *context, void (*func)() );
+/**
+ Free the memory pointed to by \c data when the memory pointed to by
+ \c context is free:d. Note that this will _not_ turn the specified
+ memory area into a valid halloc context. Only memory areas created
+ using a call to halloc() can be used as a context.
+*/
+void *halloc_register( void *context, void *data );
+#endif
diff --git a/highlight.c b/highlight.c
index 79cf45d3..1a7156d6 100644
--- a/highlight.c
+++ b/highlight.c
@@ -132,7 +132,7 @@ void highlight_shell( wchar_t * buff,
*/
wchar_t *cmd =
(last_type == TOK_STRING) ?
- expand_one(wcsdup(tok_last( &tok )),EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES) :
+ expand_one( 0, wcsdup(tok_last( &tok )),EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES) :
wcsdup(tok_last( &tok ));
if( cmd == 0 )
{
@@ -248,7 +248,7 @@ void highlight_shell( wchar_t * buff,
{
case TOK_STRING:
{
- target = expand_one( wcsdup( tok_last( &tok ) ), EXPAND_SKIP_SUBSHELL);
+ target = expand_one( 0, wcsdup( tok_last( &tok ) ), EXPAND_SKIP_SUBSHELL);
/*
Redirect filename may contain a subshell.
If so, it will be ignored/not flagged.
diff --git a/history.c b/history.c
index 887fb085..aa8d9f78 100644
--- a/history.c
+++ b/history.c
@@ -102,7 +102,7 @@ static void history_load()
is_loaded = 1;
- block();
+ signal_block();
hash_init2( &used,
&hash_wcs_func,
&hash_wcs_cmp,
@@ -124,7 +124,7 @@ static void history_load()
fclose( in_stream );
free( fn );
free( buff );
- unblock();
+ signal_unblock();
return;
}
@@ -181,7 +181,7 @@ static void history_load()
free( buff );
free( fn );
last_loaded = history_last;
- unblock();
+ signal_unblock();
}
void history_init()
diff --git a/input.c b/input.c
index f7ad7e22..bbb4a8c4 100644
--- a/input.c
+++ b/input.c
@@ -55,6 +55,7 @@ implementation in fish is as of yet incomplete.
#include "env.h"
#include "expand.h"
#include "event.h"
+#include "signal.h"
#include "translate.h"
static void input_read_inputrc( wchar_t *fn );
@@ -1085,7 +1086,7 @@ static void input_read_inputrc( wchar_t *fn )
int error=0;
// fwprintf( stderr, L"read %ls\n", fn );
- block();
+ signal_block();
rc = wfopen( fn, "r" );
if( rc )
@@ -1120,7 +1121,7 @@ static void input_read_inputrc( wchar_t *fn )
free( buff );
fclose( rc );
}
- unblock();
+ signal_unblock();
inputrc_skip_block_count=0;
inputrc_block_count=0;
diff --git a/main.c b/main.c
index 1744451a..448f6190 100644
--- a/main.c
+++ b/main.c
@@ -57,6 +57,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "event.h"
#include "output.h"
#include "translate.h"
+#include "halloc_util.h"
/**
Parse init files
@@ -73,7 +74,7 @@ static int read_init()
}
env_set( L"__fish_help_dir", DOCDIR, 0);
-
+
eval( L"builtin cd " SYSCONFDIR L" 2>/dev/null; . fish 2>/dev/null", 0, TOP );
eval( L"builtin cd 2>/dev/null;. .fish 2>/dev/null", 0, TOP );
@@ -210,9 +211,10 @@ int main( int argc, char **argv )
is_interactive_session &= isatty(STDIN_FILENO);
is_interactive_session |= force_interactive;
- translate_init();
+ common_init();
+ halloc_util_init();
+
proc_init();
- output_init();
event_init();
exec_init();
wutil_init();
@@ -220,7 +222,6 @@ int main( int argc, char **argv )
builtin_init();
function_init();
env_init();
- parse_util_init();
complete_init();
reader_init();
@@ -302,13 +303,11 @@ int main( int argc, char **argv )
reader_destroy();
parser_destroy();
wutil_destroy();
- common_destroy();
exec_destroy();
- parse_util_destroy();
event_destroy();
- output_destroy();
- translate_destroy();
+ common_destroy();
+ halloc_util_destroy();
intern_free_all();
return res;
diff --git a/output.c b/output.c
index a148e926..42669d65 100644
--- a/output.c
+++ b/output.c
@@ -43,6 +43,7 @@
#include "expand.h"
#include "common.h"
#include "output.h"
+#include "halloc_util.h"
#include "highlight.h"
/**
@@ -101,11 +102,7 @@ static size_t writestr_buff_sz=0;
*/
static char *writestr_buff = 0;
-void output_init()
-{
-}
-
-void output_destroy()
+static void output_destroy()
{
free( writestr_buff );
}
@@ -292,6 +289,12 @@ void writestr( const wchar_t *str )
*/
if( writestr_buff_sz < len )
{
+ if( !writestr_buff )
+ halloc_register_function_void( global_context, &output_destroy );
+
+
+
+
writestr_buff = realloc( writestr_buff, len );
if( !writestr_buff )
die_mem();
diff --git a/output.h b/output.h
index 6532a48b..ec008adc 100644
--- a/output.h
+++ b/output.h
@@ -116,14 +116,4 @@ int writespace( int c );
*/
int output_color_code( const wchar_t *val );
-/**
- Initialize static data
-*/
-void output_init();
-
-/**
- Destroy static data
-*/
-void output_destroy();
-
#endif
diff --git a/parse_util.c b/parse_util.c
index e9eb1d03..dbcffdb2 100644
--- a/parse_util.c
+++ b/parse_util.c
@@ -24,6 +24,7 @@
#include "expand.h"
#include "intern.h"
#include "exec.h"
+#include "halloc_util.h"
/**
Set of files which have been autoloaded
@@ -427,6 +428,36 @@ void parse_util_token_extent( const wchar_t *buff,
}
+/**
+ Free hash value, but not hash key
+*/
+static void clear_hash_value( const void *key, const void *data )
+{
+ free( (void *)data );
+}
+
+static void clear_loaded_entry( const void *key, const void *data )
+{
+ hash_table_t *loaded = (hash_table_t *)data;
+ hash_foreach( loaded,
+ &clear_hash_value );
+ hash_destroy( loaded );
+ free( loaded );
+ free( (void *)key );
+}
+
+static void parse_util_destroy()
+{
+ if( all_loaded )
+ {
+ hash_foreach( all_loaded,
+ &clear_loaded_entry );
+
+ hash_destroy( all_loaded );
+ free( all_loaded );
+ all_loaded = 0;
+ }
+}
int parse_util_load( const wchar_t *cmd,
const wchar_t *path_var,
@@ -469,6 +500,7 @@ int parse_util_load( const wchar_t *cmd,
}
hash_init( loaded, &hash_wcs_func, &hash_wcs_cmp );
hash_put( all_loaded, wcsdup(path_var), loaded );
+ halloc_register_function_void( global_context, &parse_util_destroy );
}
/*
@@ -564,38 +596,3 @@ int parse_util_load( const wchar_t *cmd,
return reloaded;
}
-void parse_util_init()
-{
-}
-
-/**
- Free hash value, but not hash key
-*/
-static void clear_hash_value( const void *key, const void *data )
-{
- free( (void *)data );
-}
-
-static void clear_loaded_entry( const void *key, const void *data )
-{
- hash_table_t *loaded = (hash_table_t *)data;
- hash_foreach( loaded,
- &clear_hash_value );
- hash_destroy( loaded );
- free( loaded );
- free( (void *)key );
-}
-
-void parse_util_destroy()
-{
- if( all_loaded )
- {
- hash_foreach( all_loaded,
- &clear_loaded_entry );
-
- hash_destroy( all_loaded );
- free( all_loaded );
- all_loaded = 0;
- }
-}
-
diff --git a/parse_util.h b/parse_util.h
index 923490d6..847260bd 100644
--- a/parse_util.h
+++ b/parse_util.h
@@ -8,6 +8,7 @@
#include <wchar.h>
+
/**
Locate the first subshell in the specified string.
@@ -78,14 +79,4 @@ int parse_util_load( const wchar_t *cmd,
void (*on_load)(const wchar_t *cmd),
int reload );
-/**
- Init the parser utility library
-*/
-void parse_util_init();
-
-/**
- Free resources used by the parser utility library
-*/
-void parse_util_destroy();
-
#endif
diff --git a/parser.c b/parser.c
index 666ca769..3db7b4b0 100644
--- a/parser.c
+++ b/parser.c
@@ -39,6 +39,7 @@ The fish parser. Contains functions for parsing code.
#include "intern.h"
#include "parse_util.h"
#include "halloc.h"
+#include "halloc_util.h"
/**
Maximum number of block levels in code. This is not the same as
@@ -340,15 +341,15 @@ static int block_count( block_t *b )
void parser_push_block( int type )
{
block_t *new = halloc( 0, sizeof( block_t ));
-
+
new->src_lineno = parser_get_lineno();
new->src_filename = parser_current_filename()?intern(parser_current_filename()):0;
// debug( 3, L"Block push %ls %d\n", parser_get_block_desc(type), block_count( current_block)+1 );
-
+
new->outer = current_block;
new->type = (current_block && current_block->skip)?FAKE:type;
-
+
/*
New blocks should be skipped if the outer block is skipped,
except TOP ans SUBST block, which open up new environments. Fake
@@ -359,9 +360,8 @@ void parser_push_block( int type )
new->skip = 0;
if( type == FAKE )
new->skip = 1;
-
+
new->job = 0;
-
new->loop_status=LOOP_NORMAL;
current_block = new;
@@ -371,20 +371,12 @@ void parser_push_block( int type )
(new->type != TOP) )
{
env_push( type == FUNCTION_CALL );
+ halloc_register_function_void( current_block, &env_pop );
}
}
void parser_pop_block()
{
-// debug( 3, L"Block pop %ls %d\n", parser_get_block_desc(current_block->type), block_count(current_block)-1 );
-
- if( (current_block->type != FUNCTION_DEF ) &&
- (current_block->type != FAKE) &&
- (current_block->type != TOP) )
- {
- env_pop();
- }
-
block_t *old = current_block;
current_block = current_block->outer;
halloc_free( old );
@@ -744,11 +736,10 @@ wchar_t *get_filename( const wchar_t *cmd )
wchar_t *path_cpy = wcsdup( path );
wchar_t *nxt_path = path;
wchar_t *state;
-
+
if( (new_cmd==0) || (path_cpy==0) )
{
die_mem();
-
}
for( nxt_path = wcstok( path_cpy, ARRAY_SEP_STR, &state );
@@ -940,7 +931,7 @@ int eval_args( const wchar_t *line, array_list_t *args )
switch(tok_last_type( &tok ) )
{
case TOK_STRING:
- switch( expand_string( wcsdup(tok_last( &tok )), args, 0 ) )
+ switch( expand_string( 0, wcsdup(tok_last( &tok )), args, 0 ) )
{
case EXPAND_ERROR:
{
@@ -979,13 +970,12 @@ int eval_args( const wchar_t *line, array_list_t *args )
do_loop=0;
break;
-
}
}
-
+
print_errors();
tok_destroy( &tok );
-
+
current_tokenizer=previous_tokenizer;
current_tokenizer_pos = previous_pos;
is_interactive = was_interactive;
@@ -1331,7 +1321,8 @@ static void parse_job_main_loop( process_t *p,
return;
}
p->pipe_fd = wcstol( tok_last( tok ), 0, 10 );
- p->argv = list_to_char_arr( j, args );
+ p->argv = list_to_char_arr( args );
+ halloc_register( j, p->argv );
p->next = halloc( j, sizeof( process_t ) );
if( p->next == 0 )
{
@@ -1353,7 +1344,8 @@ static void parse_job_main_loop( process_t *p,
case TOK_END:
{
- p->argv = list_to_char_arr( j, args );
+ p->argv = list_to_char_arr( args );
+ halloc_register( j, p->argv );
if( tok_has_next(tok))
tok_next(tok);
@@ -1399,7 +1391,7 @@ static void parse_job_main_loop( process_t *p,
}
- switch( expand_string( wcsdup(tok_last( tok )), args, 0 ) )
+ switch( expand_string( j, wcsdup(tok_last( tok )), args, 0 ) )
{
case EXPAND_ERROR:
{
@@ -1487,7 +1479,7 @@ static void parse_job_main_loop( process_t *p,
{
case TOK_STRING:
{
- target = (wchar_t *)halloc_register( j, expand_one( wcsdup( tok_last( tok ) ), 0));
+ target = (wchar_t *)expand_one( j, wcsdup( tok_last( tok ) ), 0);
if( target == 0 && error_code == 0 )
{
@@ -1634,7 +1626,7 @@ static int parse_job( process_t *p,
job_t *j,
tokenizer *tok )
{
- array_list_t args; // The list that will become the argc array for the program
+ array_list_t *args = al_halloc( j ); // The list that will become the argc array for the program
int use_function = 1; // May functions be considered when checking what action this command represents
int use_builtin = 1; // May builtins be considered when checking what action this command represents
int is_new_block=0; // Does this command create a new block?
@@ -1642,28 +1634,26 @@ static int parse_job( process_t *p,
block_t *prev_block = current_block;
int prev_tokenizer_pos = current_tokenizer_pos;
- al_init( &args );
-
current_tokenizer_pos = tok_get_pos( tok );
- while( al_get_count( &args ) == 0 )
+ while( al_get_count( args ) == 0 )
{
wchar_t *nxt=0;
switch( tok_last_type( tok ))
{
case TOK_STRING:
{
- nxt = expand_one( wcsdup(tok_last( tok )),
+ nxt = expand_one( j,
+ wcsdup(tok_last( tok )),
EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES);
-
+
if( nxt == 0 )
{
error( SYNTAX_ERROR,
tok_get_pos( tok ),
ILLEGAL_CMD_ERR_MSG,
tok_last( tok ) );
-
- al_destroy( &args );
+
current_tokenizer_pos = prev_tokenizer_pos;
return 0;
}
@@ -1677,7 +1667,6 @@ static int parse_job( process_t *p,
TOK_ERR_MSG,
tok_last(tok) );
- al_destroy( &args );
current_tokenizer_pos = prev_tokenizer_pos;
return 0;
}
@@ -1700,7 +1689,6 @@ static int parse_job( process_t *p,
tok_get_desc( tok_last_type(tok) ) );
}
- al_destroy( &args );
current_tokenizer_pos = prev_tokenizer_pos;
return 0;
}
@@ -1712,14 +1700,16 @@ static int parse_job( process_t *p,
CMD_ERR_MSG,
tok_get_desc( tok_last_type(tok) ) );
- al_destroy( &args );
current_tokenizer_pos = prev_tokenizer_pos;
return 0;
}
}
-
+
int mark = tok_get_pos( tok );
+ int consumed = 0;
+
+
if( wcscmp( L"command", nxt )==0 )
{
tok_next( tok );
@@ -1731,8 +1721,7 @@ static int parse_job( process_t *p,
{
use_function = 0;
use_builtin=0;
- free( nxt );
- continue;
+ consumed=1;
}
}
else if( wcscmp( L"builtin", nxt )==0 )
@@ -1745,8 +1734,7 @@ static int parse_job( process_t *p,
else
{
use_function = 0;
- free( nxt );
- continue;
+ consumed=1;
}
}
else if( wcscmp( L"not", nxt )==0 )
@@ -1759,8 +1747,7 @@ static int parse_job( process_t *p,
else
{
j->negate=1-j->negate;
- free( nxt );
- continue;
+ consumed=1;
}
}
else if( wcscmp( L"and", nxt )==0 )
@@ -1773,8 +1760,7 @@ static int parse_job( process_t *p,
else
{
j->skip = proc_get_last_status();
- free( nxt );
- continue;
+ consumed=1;
}
}
else if( wcscmp( L"or", nxt )==0 )
@@ -1787,8 +1773,7 @@ static int parse_job( process_t *p,
else
{
j->skip = !proc_get_last_status();
- free( nxt );
- continue;
+ consumed=1;
}
}
else if( wcscmp( L"exec", nxt )==0 )
@@ -1798,7 +1783,6 @@ static int parse_job( process_t *p,
error( SYNTAX_ERROR,
tok_get_pos( tok ),
EXEC_ERR_MSG );
- al_destroy( &args );
free(nxt);
current_tokenizer_pos = prev_tokenizer_pos;
return 0;
@@ -1814,9 +1798,8 @@ static int parse_job( process_t *p,
use_function = 0;
use_builtin=0;
p->type=INTERNAL_EXEC;
- free( nxt );
+ consumed=1;
current_tokenizer_pos = prev_tokenizer_pos;
- continue;
}
}
else if( wcscmp( L"while", nxt ) ==0 )
@@ -1844,10 +1827,8 @@ static int parse_job( process_t *p,
current_block->tok_pos = mark;
}
- free( nxt );
+ consumed=1;
is_new_block=1;
-
- continue;
}
else if( wcscmp( L"if", nxt ) ==0 )
{
@@ -1858,8 +1839,12 @@ static int parse_job( process_t *p,
current_block->param1.if_state=0;
current_block->tok_pos = mark;
- free( nxt );
is_new_block=1;
+ consumed=1;
+ }
+
+ if( consumed )
+ {
continue;
}
@@ -1892,7 +1877,7 @@ static int parse_job( process_t *p,
}
}
}
- al_push( &args, nxt );
+ al_push( args, nxt );
}
if( error_code == 0 )
@@ -1900,10 +1885,10 @@ static int parse_job( process_t *p,
if( !p->type )
{
if( use_builtin &&
- builtin_exists( (wchar_t *)al_get( &args, 0 ) ) )
+ builtin_exists( (wchar_t *)al_get( args, 0 ) ) )
{
p->type = INTERNAL_BUILTIN;
- is_new_block = parser_is_block( (wchar_t *)al_get( &args, 0 ) );
+ is_new_block = parser_is_block( (wchar_t *)al_get( args, 0 ) );
}
}
@@ -1919,7 +1904,7 @@ static int parse_job( process_t *p,
}
else
{
- p->actual_cmd = halloc_register(j, get_filename( (wchar_t *)al_get( &args, 0 ) ));
+ p->actual_cmd = halloc_register(j, get_filename( (wchar_t *)al_get( args, 0 ) ));
/*
Check if the specified command exists
@@ -1933,16 +1918,16 @@ static int parse_job( process_t *p,
implicit command.
*/
wchar_t *pp =
- parser_cdpath_get( (wchar_t *)al_get( &args, 0 ) );
+ parser_cdpath_get( (wchar_t *)al_get( args, 0 ) );
if( pp )
{
wchar_t *tmp;
free( pp );
- tmp = (wchar_t *)al_get( &args, 0 );
- al_truncate( &args, 0 );
- al_push( &args, wcsdup( L"cd" ) );
- al_push( &args, tmp );
+ tmp = (wchar_t *)al_get( args, 0 );
+ al_truncate( args, 0 );
+ al_push( args, wcsdup( L"cd" ) );
+ al_push( args, tmp );
/*
If we have defined a wrapper around cd, use it,
otherwise use the cd builtin
@@ -1954,12 +1939,12 @@ static int parse_job( process_t *p,
}
else
{
- if( wcschr( (wchar_t *)al_get( &args, 0 ), L'=' ) )
+ if( wcschr( (wchar_t *)al_get( args, 0 ), L'=' ) )
{
error( EVAL_ERROR,
tok_get_pos( tok ),
COMMAND_ASSIGN_ERR_MSG,
- (wchar_t *)al_get( &args, 0 ) );
+ (wchar_t *)al_get( args, 0 ) );
}
@@ -1968,7 +1953,7 @@ static int parse_job( process_t *p,
error( EVAL_ERROR,
tok_get_pos( tok ),
_(L"Unknown command '%ls'"),
- (wchar_t *)al_get( &args, 0 ) );
+ (wchar_t *)al_get( args, 0 ) );
}
}
@@ -1990,6 +1975,7 @@ static int parse_job( process_t *p,
error( SYNTAX_ERROR,
tok_get_pos( tok ),
BLOCK_END_ERR_MSG );
+
}
if( !make_sub_block )
@@ -2028,8 +2014,8 @@ static int parse_job( process_t *p,
end_pos - current_tokenizer_pos);
p->type = INTERNAL_BLOCK;
- free( (void *)al_get( &args, 0 ) );
- al_set( &args, 0, sub_block );
+ free( (void *)al_get( args, 0 ) );
+ al_set( args, 0, sub_block );
tok_set_pos( tok,
end_pos );
@@ -2047,22 +2033,20 @@ static int parse_job( process_t *p,
if( !error_code )
{
- if( p->type == INTERNAL_BUILTIN && parser_skip_arguments( (wchar_t *)al_get(&args, 0) ) )
+ if( p->type == INTERNAL_BUILTIN && parser_skip_arguments( (wchar_t *)al_get(args, 0) ) )
{
- p->argv = list_to_char_arr( j, &args );
+ p->argv = list_to_char_arr( args );
+ halloc_register( j, p->argv );
// tok_next(tok);
}
else
{
- parse_job_main_loop( p, j, tok, &args );
+ parse_job_main_loop( p, j, tok, args );
}
}
if( error_code )
{
- if( !p->argv )
- al_foreach( &args,
- (void (*)(const void *))&free );
/*
Make sure the block stack is consistent
*/
@@ -2070,9 +2054,7 @@ static int parse_job( process_t *p,
{
parser_pop_block();
}
-
}
- al_destroy( &args );
current_tokenizer_pos = prev_tokenizer_pos;
return !error_code;
}
diff --git a/proc.c b/proc.c
index 08a74cb9..f804e8bf 100644
--- a/proc.c
+++ b/proc.c
@@ -109,6 +109,7 @@ void proc_init()
sb_init( &event_status );
}
+
/**
Remove job from list of jobs
*/
diff --git a/signal.c b/signal.c
index d6f3be8c..dbd3b701 100644
--- a/signal.c
+++ b/signal.c
@@ -43,6 +43,9 @@ struct lookup_entry
const wchar_t *desc;
};
+static int block_count=0;
+
+
/**
Lookup table used to convert between signal names and signal ids,
etc.
@@ -536,13 +539,22 @@ void signal_handle( int sig, int do_handle )
void signal_block()
{
sigset_t chldset;
- sigfillset( &chldset );
- sigprocmask(SIG_BLOCK, &chldset, 0);
+
+ if( !block_count )
+ {
+ sigfillset( &chldset );
+ sigprocmask(SIG_BLOCK, &chldset, 0);
+ }
+ block_count++;
}
void signal_unblock()
{
sigset_t chldset;
- sigfillset( &chldset );
- sigprocmask(SIG_UNBLOCK, &chldset, 0);
+ block_count--;
+ if( !block_count )
+ {
+ sigfillset( &chldset );
+ sigprocmask(SIG_UNBLOCK, &chldset, 0);
+ }
}
diff --git a/translate.c b/translate.c
index c26be6fc..4a109ecd 100644
--- a/translate.c
+++ b/translate.c
@@ -17,6 +17,7 @@ Translation library, internally uses catgets
#include "common.h"
#include "util.h"
+#include "halloc_util.h"
#if HAVE_GETTEXT
@@ -45,6 +46,21 @@ static size_t wcs2str_buff_count=0;
static int is_init = 0;
+static void internal_destroy()
+{
+ int i;
+
+ if( !is_init )
+ return;
+
+ is_init = 0;
+
+ for(i=0; i<BUFF_COUNT; i++ )
+ sb_destroy( &buff[i] );
+
+ free( wcs2str_buff );
+}
+
static void internal_init()
{
int i;
@@ -52,7 +68,10 @@ static void internal_init()
is_init = 1;
for(i=0; i<BUFF_COUNT; i++ )
+ {
sb_init( &buff[i] );
+ }
+ halloc_register_function_void( global_context, &internal_destroy );
bindtextdomain( PACKAGE_NAME, LOCALEDIR );
textdomain( PACKAGE_NAME );
@@ -103,26 +122,6 @@ const wchar_t *wgettext( const wchar_t *in )
return wres;
}
-
-void translate_init()
-{
-}
-
-void translate_destroy()
-{
- int i;
-
- if( !is_init )
- return;
-
- is_init = 0;
-
- for(i=0; i<BUFF_COUNT; i++ )
- sb_destroy( &buff[i] );
-
- free( wcs2str_buff );
-}
-
#else
const wchar_t *wgettext( const wchar_t *in )
@@ -130,12 +129,4 @@ const wchar_t *wgettext( const wchar_t *in )
return in;
}
-void translate_init()
-{
-}
-
-void translate_destroy()
-{
-}
-
#endif
diff --git a/translate.h b/translate.h
index 22d3848f..19123587 100644
--- a/translate.h
+++ b/translate.h
@@ -19,11 +19,3 @@ Translation library, internally uses catgets
*/
const wchar_t *wgettext( const wchar_t *in );
-/**
- Initialize (or reinitialize) the translation library
-*/
-void translate_init();
-/**
- Free memory used by the translation library
-*/
-void translate_destroy();