Initial blocking implementation

darcs-hash:20051211222101-ac50b-6e11220bd608187fbb32a0313b5b73dbdc8354fc.gz
This commit is contained in:
axel 2005-12-12 08:21:01 +10:00
parent 2cac04850b
commit 1d69e70b7a
11 changed files with 390 additions and 68 deletions

View file

@ -79,13 +79,13 @@ MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
BUILTIN_DOC_SRC := doc_src/source.txt doc_src/and.txt \ BUILTIN_DOC_SRC := doc_src/source.txt doc_src/and.txt \
doc_src/begin.txt doc_src/bg.txt doc_src/bind.txt \ doc_src/begin.txt doc_src/bg.txt doc_src/bind.txt \
doc_src/break.txt doc_src/builtin.txt doc_src/case.txt \ doc_src/block.txt doc_src/break.txt doc_src/builtin.txt \
doc_src/cd.txt doc_src/command.txt doc_src/commandline.txt \ doc_src/case.txt doc_src/cd.txt doc_src/command.txt \
doc_src/complete.txt doc_src/continue.txt doc_src/else.txt \ doc_src/commandline.txt doc_src/complete.txt doc_src/continue.txt \
doc_src/end.txt doc_src/eval.txt doc_src/exec.txt doc_src/exit.txt \ doc_src/else.txt doc_src/end.txt doc_src/eval.txt doc_src/exec.txt \
doc_src/fg.txt doc_src/for.txt doc_src/function.txt \ doc_src/exit.txt doc_src/fg.txt doc_src/for.txt \
doc_src/functions.txt doc_src/if.txt doc_src/jobs.txt \ doc_src/function.txt doc_src/functions.txt doc_src/if.txt \
doc_src/not.txt doc_src/or.txt doc_src/random.txt \ doc_src/jobs.txt doc_src/not.txt doc_src/or.txt doc_src/random.txt \
doc_src/return.txt doc_src/read.txt doc_src/set.txt \ doc_src/return.txt doc_src/read.txt doc_src/set.txt \
doc_src/status.txt doc_src/switch.txt doc_src/ulimit.txt \ doc_src/status.txt doc_src/switch.txt doc_src/ulimit.txt \
doc_src/while.txt doc_src/while.txt

182
builtin.c
View file

@ -244,6 +244,173 @@ static int builtin_bind( wchar_t **argv )
return 0; return 0;
} }
/**
The block builtin, used for temporarily blocking events
*/
static int builtin_block( wchar_t **argv )
{
enum
{
UNSET,
GLOBAL,
LOCAL,
}
;
int scope=UNSET;
int erase = 0;
int argc=builtin_count_args( argv );
int type = (1<<EVENT_ANY);
woptind=0;
const static struct woption
long_options[] =
{
{
L"erase", no_argument, 0, 'e'
}
,
{
L"local", no_argument, 0, 'l'
}
,
{
L"global", no_argument, 0, 'g'
}
,
{
L"help", no_argument, 0, 'h'
}
,
{
0, 0, 0, 0
}
}
;
while( 1 )
{
int opt_index = 0;
int opt = wgetopt_long( argc,
argv,
L"elgh",
long_options,
&opt_index );
if( opt == -1 )
break;
switch( opt )
{
case 0:
if(long_options[opt_index].flag != 0)
break;
sb_append2( sb_err,
argv[0],
BUILTIN_ERR_UNKNOWN,
L" ",
long_options[opt_index].name,
L"\n",
(void *)0);
builtin_print_help( argv[0], sb_err );
return 1;
case 'h':
builtin_print_help( argv[0], sb_err );
return 0;
case 'g':
scope = GLOBAL;
break;
case 'l':
scope = LOCAL;
break;
case 'e':
erase = 1;
break;
case '?':
builtin_print_help( argv[0], sb_err );
return 1;
}
}
if( erase )
{
if( scope != UNSET )
{
sb_printf( sb_err, L"%ls: Can not specify scope when removing block\n", argv[0] );
return 1;
}
if( !global_event_block )
{
sb_printf( sb_err, L"%ls: No blocks defined\n", argv[0] );
return 1;
}
event_block_t *eb = global_event_block;
global_event_block = eb->next;
free( eb );
}
else
{
block_t *block=current_block;
event_block_t *eb = malloc( sizeof( event_block_t ) );
if( !eb )
die_mem();
eb->type = type;
switch( scope )
{
case LOCAL:
{
if( !block->outer )
block=0;
break;
}
case GLOBAL:
{
block=0;
}
case UNSET:
{
while( block && block->type != FUNCTION_CALL )
block = block->outer;
}
}
if( block )
{
eb->next = block->first_event_block;
block->first_event_block = eb;
}
else
{
eb->next = global_event_block;
global_event_block=eb;
}
}
return 0;
}
/** /**
The builtin builtin, used for given builtins precedence over functions. Mostly handled by the parser. All this code does is some additional operational modes, such as printing a list of all builtins. The builtin builtin, used for given builtins precedence over functions. Mostly handled by the parser. All this code does is some additional operational modes, such as printing a list of all builtins.
@ -838,7 +1005,7 @@ static int builtin_function( wchar_t **argv )
break; break;
} }
e = malloc( sizeof(event_t)); e = calloc( 1, sizeof(event_t));
if( !e ) if( !e )
die_mem(); die_mem();
e->type = EVENT_SIGNAL; e->type = EVENT_SIGNAL;
@ -862,7 +1029,7 @@ static int builtin_function( wchar_t **argv )
break; break;
} }
e = malloc( sizeof(event_t)); e = calloc( 1, sizeof(event_t));
if( !e ) if( !e )
die_mem(); die_mem();
e->type = EVENT_VARIABLE; e->type = EVENT_VARIABLE;
@ -879,7 +1046,7 @@ static int builtin_function( wchar_t **argv )
wchar_t *end; wchar_t *end;
event_t *e; event_t *e;
e = malloc( sizeof(event_t)); e = calloc( 1, sizeof(event_t));
if( !e ) if( !e )
die_mem(); die_mem();
@ -2850,6 +3017,7 @@ void builtin_init()
hash_init( &builtin, &hash_wcs_func, &hash_wcs_cmp ); hash_init( &builtin, &hash_wcs_func, &hash_wcs_cmp );
hash_put( &builtin, L"exit", (void*) &builtin_exit ); hash_put( &builtin, L"exit", (void*) &builtin_exit );
hash_put( &builtin, L"block", (void*) &builtin_block );
hash_put( &builtin, L"builtin", (void*) &builtin_builtin ); hash_put( &builtin, L"builtin", (void*) &builtin_builtin );
hash_put( &builtin, L"cd", (void*) &builtin_cd ); hash_put( &builtin, L"cd", (void*) &builtin_cd );
hash_put( &builtin, L"function", (void*) &builtin_function ); hash_put( &builtin, L"function", (void*) &builtin_function );
@ -2899,6 +3067,7 @@ void builtin_init()
intern_static( L"exit" ); intern_static( L"exit" );
intern_static( L"builtin" ); intern_static( L"builtin" );
intern_static( L"block" );
intern_static( L"cd" ); intern_static( L"cd" );
intern_static( L"function" ); intern_static( L"function" );
intern_static( L"functions" ); intern_static( L"functions" );
@ -3026,11 +3195,13 @@ const wchar_t *builtin_get_desc( const wchar_t *b )
hash_init( desc, &hash_wcs_func, &hash_wcs_cmp ); hash_init( desc, &hash_wcs_func, &hash_wcs_cmp );
hash_put( desc, L"exit", L"Exit the shell" ); hash_put( desc, L"block", L"Temporarily block delivery of events" );
hash_put( desc, L"builtin", L"Run a builtin command" );
hash_put( desc, L"complete", L"Edit command specific completions" );
hash_put( desc, L"cd", L"Change working directory" ); hash_put( desc, L"cd", L"Change working directory" );
hash_put( desc, L"exit", L"Exit the shell" );
hash_put( desc, L"function", L"Define a new function" ); hash_put( desc, L"function", L"Define a new function" );
hash_put( desc, L"functions", L"List or remove functions" ); hash_put( desc, L"functions", L"List or remove functions" );
hash_put( desc, L"complete", L"Edit command specific completions" );
hash_put( desc, L"end", L"End a block of commands" ); hash_put( desc, L"end", L"End a block of commands" );
hash_put( desc, L"else", L"Evaluate block if condition is false" ); hash_put( desc, L"else", L"Evaluate block if condition is false" );
hash_put( desc, L"eval", L"Evaluate parameters as a command" ); hash_put( desc, L"eval", L"Evaluate parameters as a command" );
@ -3047,7 +3218,6 @@ const wchar_t *builtin_get_desc( const wchar_t *b )
hash_put( desc, L"commandline", L"Set the commandline" ); hash_put( desc, L"commandline", L"Set the commandline" );
hash_put( desc, L"switch", L"Conditionally execute a block of commands" ); hash_put( desc, L"switch", L"Conditionally execute a block of commands" );
hash_put( desc, L"case", L"Conditionally execute a block of commands" ); hash_put( desc, L"case", L"Conditionally execute a block of commands" );
hash_put( desc, L"builtin", L"Run a builtin command" );
hash_put( desc, L"command", L"Run a program" ); hash_put( desc, L"command", L"Run a program" );
hash_put( desc, L"if", L"Conditionally execute a command" ); hash_put( desc, L"if", L"Conditionally execute a command" );
hash_put( desc, L"while", L"Perform a command multiple times" ); hash_put( desc, L"while", L"Perform a command multiple times" );

View file

@ -682,6 +682,7 @@ builtins or shellscript functions, and can only be used inside fish.
- <a href="builtins.html#begin">begin</a>, execute a block of commands - <a href="builtins.html#begin">begin</a>, execute a block of commands
- <a href="builtins.html#bind">bind</a>, change keyboard bindings - <a href="builtins.html#bind">bind</a>, change keyboard bindings
- <a href="builtins.html#break">break</a>, stop the execution of a loop - <a href="builtins.html#break">break</a>, stop the execution of a loop
- <a href="builtins.html#block">block</a>, Temporarily block delivery of events
- <a href="builtins.html#builtin">builtin</a>, execute a builtin command - <a href="builtins.html#builtin">builtin</a>, execute a builtin command
- <a href="builtins.html#case">case</a>, conditionally execute a block of commands - <a href="builtins.html#case">case</a>, conditionally execute a block of commands
- <a href="builtins.html#cd">cd</a>, change the current directory - <a href="builtins.html#cd">cd</a>, change the current directory
@ -995,7 +996,10 @@ g++, javac, java, gcj, lpr, doxygen, whois, find)
- Check keybinding commands for output - if non has happened, don't repaint to reduce flicker - Check keybinding commands for output - if non has happened, don't repaint to reduce flicker
- The jobs builtin should be able to give information on a specific job, such as the pids of the processes in the job - The jobs builtin should be able to give information on a specific job, such as the pids of the processes in the job
- Syntax highlighting should mark cd to non-existing directories as an error - Syntax highlighting should mark cd to non-existing directories as an error
- the code for printing the prompt should know about the most common escape sequences
- block builtin
- redo the jobs command
- wait shellscript
\subsection todo-possible Possible features \subsection todo-possible Possible features

24
env.c
View file

@ -236,7 +236,6 @@ static void universal_callback( int type,
if( str ) if( str )
{ {
array_list_t arg;
event_t ev; event_t ev;
has_changed=1; has_changed=1;
@ -245,12 +244,12 @@ static void universal_callback( int type,
ev.param1.variable=name; ev.param1.variable=name;
ev.function_name=0; ev.function_name=0;
al_init( &arg ); al_init( &ev.arguments );
al_push( &arg, L"VARIABLE" ); al_push( &ev.arguments, L"VARIABLE" );
al_push( &arg, str ); al_push( &ev.arguments, str );
al_push( &arg, name ); al_push( &ev.arguments, name );
event_fire( &ev, &arg ); event_fire( &ev );
al_destroy( &arg ); al_destroy( &ev.arguments );
} }
} }
@ -489,7 +488,6 @@ void env_set( const wchar_t *key,
int done=0; int done=0;
event_t ev; event_t ev;
array_list_t ev_list;
int is_universal = 0; int is_universal = 0;
if( (var_mode & ENV_USER ) && if( (var_mode & ENV_USER ) &&
@ -669,14 +667,14 @@ void env_set( const wchar_t *key,
ev.param1.variable = key; ev.param1.variable = key;
ev.function_name = 0; ev.function_name = 0;
al_init( &ev_list ); al_init( &ev.arguments );
al_push( &ev_list, L"VARIABLE" ); al_push( &ev.arguments, L"VARIABLE" );
al_push( &ev_list, key ); al_push( &ev.arguments, key );
// debug( 1, L"env_set: fire events on variable %ls", key ); // debug( 1, L"env_set: fire events on variable %ls", key );
event_fire( &ev, &ev_list ); event_fire( &ev );
// debug( 1, L"env_set: return from event firing" ); // debug( 1, L"env_set: return from event firing" );
al_destroy( &ev_list ); al_destroy( &ev.arguments );
} }
} }

135
event.c
View file

@ -67,6 +67,12 @@ static array_list_t *events;
*/ */
static array_list_t *killme; static array_list_t *killme;
/**
List of events that have been sent but have not yet been delivered because they are blocked.
*/
static array_list_t *blocked;
/** /**
Tests if one event instance matches the definition of a event Tests if one event instance matches the definition of a event
class. If the class defines a function name, that will also be a class. If the class defines a function name, that will also be a
@ -120,7 +126,7 @@ static int event_match( event_t *class, event_t *instance )
Create an identical copy of an event. Use deep copying, i.e. make Create an identical copy of an event. Use deep copying, i.e. make
duplicates of any strings used as well. duplicates of any strings used as well.
*/ */
static event_t *event_copy( event_t *event ) static event_t *event_copy( event_t *event, int copy_arguments )
{ {
event_t *e = malloc( sizeof( event_t ) ); event_t *e = malloc( sizeof( event_t ) );
if( !e ) if( !e )
@ -133,12 +139,55 @@ static event_t *event_copy( event_t *event )
if( e->type == EVENT_VARIABLE ) if( e->type == EVENT_VARIABLE )
e->param1.variable = wcsdup( e->param1.variable ); e->param1.variable = wcsdup( e->param1.variable );
al_init( &e->arguments );
if( copy_arguments )
{
int i;
for( i=0; i<al_get_count( &event->arguments ); i++ )
{
al_push( &e->arguments, wcsdup( (wchar_t *)al_get( &event->arguments, i ) ) );
}
}
return e; return e;
} }
static int event_is_blocked( event_t *e )
{
block_t *block;
event_block_t *eb;
for( block = current_block; block; block = block->outer )
{
for( eb = block->first_event_block; eb; eb=eb->next )
{
if( eb->type & (1<<EVENT_ANY ) )
return 1;
if( eb->type & (1<<e->type) )
return 1;
}
}
for( eb = global_event_block; eb; eb=eb->next )
{
if( eb->type & (1<<EVENT_ANY ) )
return 1;
if( eb->type & (1<<e->type) )
return 1;
return 1;
}
return 0;
}
void event_add_handler( event_t *event ) void event_add_handler( event_t *event )
{ {
event_t *e = event_copy( event ); event_t *e;
e = event_copy( event, 0 );
if( !events ) if( !events )
events = al_new(); events = al_new();
@ -268,7 +317,7 @@ static int event_is_killed( event_t *e )
matches' path. This means that nothing is allocated/initialized matches' path. This means that nothing is allocated/initialized
unless that is needed. unless that is needed.
*/ */
static void event_fire_internal( event_t *event, array_list_t *arguments ) static void event_fire_internal( event_t *event )
{ {
int i, j; int i, j;
string_buffer_t *b=0; string_buffer_t *b=0;
@ -337,9 +386,9 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
sb_append( b, criterion->function_name ); sb_append( b, criterion->function_name );
for( j=0; j<al_get_count(arguments); j++ ) for( j=0; j<al_get_count(&event->arguments); j++ )
{ {
wchar_t *arg_esc = escape( (wchar_t *)al_get( arguments, j), 0 ); wchar_t *arg_esc = escape( (wchar_t *)al_get( &event->arguments, j), 0 );
sb_append( b, L" " ); sb_append( b, L" " );
sb_append( b, arg_esc ); sb_append( b, arg_esc );
free( arg_esc ); free( arg_esc );
@ -385,15 +434,42 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
/** /**
Handle all pending signal events Handle all pending signal events
*/ */
static void event_fire_signal_events() static void event_fire_delayed()
{ {
int i;
if( blocked && is_event==1)
{
array_list_t *new_blocked = 0;
for( i=0; i<al_get_count( blocked ); i++ )
{
event_t *e = (event_t *)al_get( blocked, i );
if( event_is_blocked( e ) )
{
if( !new_blocked )
new_blocked = al_new();
al_push( new_blocked, e );
}
else
{
event_fire_internal( e );
event_free( e );
}
}
al_destroy( blocked );
free( blocked );
blocked = new_blocked;
}
while( sig_list[active_list].count > 0 ) while( sig_list[active_list].count > 0 )
{ {
int i;
signal_list_t *lst; signal_list_t *lst;
event_t e; event_t e;
array_list_t a; al_init( &e.arguments );
al_init( &a );
/* /*
Switch signal lists Switch signal lists
@ -421,17 +497,26 @@ static void event_fire_signal_events()
for( i=0; i<lst->count; i++ ) for( i=0; i<lst->count; i++ )
{ {
e.param1.signal = lst->signal[i]; e.param1.signal = lst->signal[i];
al_set( &a, 0, sig2wcs( e.param1.signal ) ); al_set( &e.arguments, 0, sig2wcs( e.param1.signal ) );
event_fire_internal( &e, &a ); if( event_is_blocked( &e ) )
{
if( !blocked )
blocked = al_new();
al_push( blocked, event_copy(&e, 1) );
}
else
{
event_fire_internal( &e );
}
} }
al_destroy( &a ); al_destroy( &e.arguments );
} }
} }
void event_fire( event_t *event, array_list_t *arguments ) void event_fire( event_t *event )
{ {
//int is_event_old = is_event; //int is_event_old = is_event;
is_event++; is_event++;
@ -452,10 +537,23 @@ void event_fire( event_t *event, array_list_t *arguments )
} }
else else
{ {
event_fire_signal_events();
event_fire_delayed();
if( event ) if( event )
event_fire_internal( event, arguments ); {
if( event_is_blocked( event ) )
{
if( !blocked )
blocked = al_new();
al_push( blocked, event_copy(event, 1) );
}
else
{
event_fire_internal( event );
}
}
} }
is_event--;// = is_event_old; is_event--;// = is_event_old;
@ -487,9 +585,14 @@ void event_destroy()
void event_free( event_t *e ) void event_free( event_t *e )
{ {
/*
When apropriate, we clear the argument vector
*/
al_foreach( &e->arguments, (void (*)(const void *))&free );
al_destroy( &e->arguments );
free( (void *)e->function_name ); free( (void *)e->function_name );
if( e->type == EVENT_VARIABLE ) if( e->type == EVENT_VARIABLE )
free( (void *)e->param1.variable ); free( (void *)e->param1.variable );
free( e ); free( e );
} }

15
event.h
View file

@ -43,7 +43,8 @@ typedef struct
union union
{ {
/** /**
Signal number for signal-type events.Use EVENT_ANY_SIGNAL to match any signal Signal number for signal-type events.Use EVENT_ANY_SIGNAL
to match any signal
*/ */
int signal; int signal;
/** /**
@ -51,7 +52,8 @@ typedef struct
*/ */
const wchar_t *variable; const wchar_t *variable;
/** /**
Process id for process-type events. Use EVENT_ANY_PID to match any pid. Process id for process-type events. Use EVENT_ANY_PID to
match any pid.
*/ */
pid_t pid; pid_t pid;
/** /**
@ -65,6 +67,13 @@ typedef struct
The name of the event handler function The name of the event handler function
*/ */
const wchar_t *function_name; const wchar_t *function_name;
/**
The argument list. Only used when sending a new event using
event_fire. In all other situations, the value of this variable
is ignored.
*/
array_list_t arguments;
} }
event_t; event_t;
@ -98,7 +107,7 @@ int event_get( event_t *criterion, array_list_t *out );
\param event the specific event whose handlers should fire \param event the specific event whose handlers should fire
\param arguments the argument string to send to the event handler function \param arguments the argument string to send to the event handler function
*/ */
void event_fire( event_t *event, array_list_t *arguments ); void event_fire( event_t *event );
/** /**
Initialize the event-handling library Initialize the event-handling library

View file

@ -1270,7 +1270,7 @@ static int interrupt_handler()
/* /*
Fire any pending events Fire any pending events
*/ */
event_fire( 0, 0 ); event_fire( 0 );
if( job_reap( 1 ) ) if( job_reap( 1 ) )
repaint(); repaint();
if( reader_interupted() ) if( reader_interupted() )

View file

@ -111,6 +111,8 @@ The fish parser. Contains functions for parsing code.
/** Last error code */ /** Last error code */
int error_code; int error_code;
event_block_t *global_event_block=0;
/** Position of last error */ /** Position of last error */
static int err_pos; static int err_pos;
@ -194,7 +196,7 @@ int block_count( block_t *b )
void parser_push_block( int type ) void parser_push_block( int type )
{ {
block_t *new = malloc( sizeof( block_t )); block_t *new = calloc( 1, sizeof( block_t ));
// debug( 2, L"Block push %ls %d\n", bl[type], block_count( current_block)+1 ); // debug( 2, L"Block push %ls %d\n", bl[type], block_count( current_block)+1 );
new->outer = current_block; new->outer = current_block;
@ -230,6 +232,7 @@ void parser_push_block( int type )
void parser_pop_block() void parser_pop_block()
{ {
// debug( 2, L"Block pop %ls %d\n", bl[current_block->type], block_count(current_block)-1 ); // debug( 2, L"Block pop %ls %d\n", bl[current_block->type], block_count(current_block)-1 );
event_block_t *eb, *eb_next;
if( (current_block->type != FUNCTION_DEF ) && if( (current_block->type != FUNCTION_DEF ) &&
(current_block->type != FAKE) && (current_block->type != FAKE) &&
@ -270,6 +273,12 @@ void parser_pop_block()
} }
for( eb=current_block->first_event_block; eb; eb=eb_next )
{
eb_next = eb->next;
free(eb);
}
block_t *old = current_block; block_t *old = current_block;
current_block = current_block->outer; current_block = current_block->outer;
free( old ); free( old );
@ -1996,7 +2005,7 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
tok_init( current_tokenizer, cmd, 0 ); tok_init( current_tokenizer, cmd, 0 );
error_code = 0; error_code = 0;
event_fire( 0, 0 ); event_fire( 0 );
while( tok_has_next( current_tokenizer ) && while( tok_has_next( current_tokenizer ) &&
!error_code && !error_code &&
@ -2004,7 +2013,7 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type )
!exit_status() ) !exit_status() )
{ {
eval_job( current_tokenizer ); eval_job( current_tokenizer );
event_fire( 0, 0 ); event_fire( 0 );
} }
int prev_block_type = current_block->type; int prev_block_type = current_block->type;

View file

@ -11,6 +11,27 @@
#include "util.h" #include "util.h"
#include "parser.h" #include "parser.h"
typedef struct event_block
{
/**
The types of events to block. This is interpreted as a bitset
whete the value is 1 for every bit corresponding to a blocked
event type. For example, if EVENT_VARIABLE type events should
be blocked, (type & 1<<EVENT_BLOCKED) should be set.
Note that EVENT_ANY can be used to specify any event.
*/
int type;
/**
The next event_block struct
*/
struct event_block *next;
}
event_block_t;
/** /**
block_t represents a block of commands. block_t represents a block of commands.
*/ */
@ -21,12 +42,12 @@ typedef struct block
int tok_pos; /**< The start index of the block */ int tok_pos; /**< The start index of the block */
/** /**
Status for the current loop block. Can be anu of the values from the loop_status enum. Status for the current loop block. Can be any of the values from the loop_status enum.
*/ */
int loop_status; int loop_status;
/** /**
The log that is currently evaluated in the specified block. The job that is currently evaluated in the specified block.
*/ */
job_t *job; job_t *job;
@ -68,7 +89,10 @@ typedef struct block
array_list_t *function_events; array_list_t *function_events;
} param4; } param4;
/**
Some naming confusion. This is a pointer to the first element in the list of all event blocks.
*/
event_block_t *first_event_block;
/** /**
Next outer block Next outer block
@ -159,6 +183,10 @@ enum parser_error
/** The current innermost block */ /** The current innermost block */
extern block_t *current_block; extern block_t *current_block;
/** Global event blocks */
extern event_block_t *global_event_block;
/** The current error code */ /** The current error code */
extern int error_code; extern int error_code;

25
proc.c
View file

@ -76,9 +76,10 @@ int proc_had_barrier;
pid_t proc_last_bg_pid = 0; pid_t proc_last_bg_pid = 0;
/** /**
List used to store arguments when firing events The event variable used to send all process event
*/ */
static array_list_t event_arg; static event_t event;
/** /**
Stringbuffer used to create arguments when firing events Stringbuffer used to create arguments when firing events
*/ */
@ -91,7 +92,7 @@ static string_buffer_t event_status;
void proc_init() void proc_init()
{ {
al_init( &event_arg ); al_init( &event.arguments );
sb_init( &event_pid ); sb_init( &event_pid );
sb_init( &event_status ); sb_init( &event_status );
} }
@ -185,7 +186,7 @@ void job_free( job_t * j )
void proc_destroy() void proc_destroy()
{ {
al_destroy( &event_arg ); al_destroy( &event.arguments );
sb_destroy( &event_pid ); sb_destroy( &event_pid );
sb_destroy( &event_status ); sb_destroy( &event_status );
while( first_job ) while( first_job )
@ -484,21 +485,21 @@ static void format_job_info( const job_t *j, const wchar_t *status )
void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status ) void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status )
{ {
static event_t ev;
ev.type=type; event.type=type;
ev.param1.pid = pid; event.param1.pid = pid;
al_push( &event_arg, msg ); al_push( &event.arguments, msg );
sb_printf( &event_pid, L"%d", pid ); sb_printf( &event_pid, L"%d", pid );
al_push( &event_arg, event_pid.buff ); al_push( &event.arguments, event_pid.buff );
sb_printf( &event_status, L"%d", status ); sb_printf( &event_status, L"%d", status );
al_push( &event_arg, event_status.buff ); al_push( &event.arguments, event_status.buff );
event_fire( &ev, &event_arg ); event_fire( &event );
al_truncate( &event_arg, 0 );
al_truncate( &event.arguments, 0 );
sb_clear( &event_pid ); sb_clear( &event_pid );
sb_clear( &event_status ); sb_clear( &event_status );
} }

View file

@ -305,7 +305,7 @@ static void default_handler(int signal, siginfo_t *info, void *context)
e.param1.signal = signal; e.param1.signal = signal;
e.function_name=0; e.function_name=0;
event_fire( &e, 0 ); event_fire( &e );
} }
/** /**