Remove old event hooks, add more event handler documentation

darcs-hash:20051203194618-ac50b-e90683cb69b19da789152164a89a34bf187fd4e4.gz
This commit is contained in:
axel 2005-12-04 05:46:18 +10:00
parent 9b4c34aa4c
commit 32e833f331
9 changed files with 57 additions and 30 deletions

View File

@ -2322,7 +2322,7 @@ static int builtin_jobs( wchar_t **argv )
sb_printf( sb_out, L"%d\t%d\t", j->job_id, j->pgid ); sb_printf( sb_out, L"%d\t%d\t", j->job_id, j->pgid );
#ifdef HAVE__PROC_SELF_STAT #ifdef HAVE__PROC_SELF_STAT
sb_printf( sb_out, L"%d\t", cpu_use(j) ); sb_printf( sb_out, L"%d%%\t", cpu_use(j) );
#endif #endif
sb_append2( sb_out, job_is_stopped(j)?L"stopped\t":L"running\t", sb_append2( sb_out, job_is_stopped(j)?L"stopped\t":L"running\t",
// job_is_completed(j)?L"completed\t":L"unfinished\t", // job_is_completed(j)?L"completed\t":L"unfinished\t",

View File

@ -757,9 +757,12 @@ order. If you want to run a command only on starting an interactive
shell, use the output of the 'status --is-interactive' command. If shell, use the output of the 'status --is-interactive' command. If
you want to run a command only on starting a login shell, use 'status --is-login' instead. you want to run a command only on starting a login shell, use 'status --is-login' instead.
If you want to run a set of commands when \c fish exits, redefine the If you want to run a set of commands when \c fish exits, use an <a href='#event'>event
<a href="#hooks">function hook</a> \c fish_on_exit. If the \c handler</a> that is triggered by the exit of the shell:
fish_on_exit is defined, it will be execute before the shell exits.
<pre>function on_exit --on-process %self
echo fish is now exiting
end</pre>
<a href="#variables-universal">Universal variables</a> are stored in <a href="#variables-universal">Universal variables</a> are stored in
the file .fishd.HOSTNAME, where HOSTNAME is the name of your the file .fishd.HOSTNAME, where HOSTNAME is the name of your
@ -841,15 +844,28 @@ end
</pre> </pre>
</p> </p>
\subsection hooks Event hooks \subsection event Event handlers
There are several special function names in fish. If a function is When defining a new function in fish, it is possible to make it into an
given this name, it will be automatically called when a specific event event handler, i.e. a function that is automatically run when a
has occured. These functions are: specific event takes place. Events that can trigger a handler currently are:
- \c fish_on_exit, which is called before the shell exits * When a signal is delivered
- \c fish_on_exec, which is called before interactively executing a command * When a process or job exits
- \c fish_on_return, which is called when control returns to the shell after interactively executing a command * When the value of a variable is updated
Example:
To specify a signal handler for the WINCH signal, write:
<pre>function --on-signal WINCH my_signal_handler
echo Got WINCH signal!
end
</pre>
For more information on how to define new event handlers, see the
documentation for the <a href='builtins.html#function'>function</a>
command.
\section issues Common issues with fish \section issues Common issues with fish

18
event.c
View File

@ -273,6 +273,9 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
int i, j; int i, j;
string_buffer_t *b=0; string_buffer_t *b=0;
array_list_t *fire=0; array_list_t *fire=0;
int was_subshell = is_subshell;
int was_interactive = is_interactive;
/* /*
First we free all events that have been removed First we free all events that have been removed
@ -344,15 +347,22 @@ static void event_fire_internal( event_t *event, array_list_t *arguments )
// debug( 1, L"Event handler fires command '%ls'", (wchar_t *)b->buff ); // debug( 1, L"Event handler fires command '%ls'", (wchar_t *)b->buff );
/*
Event handlers are not part of the main flow of code, so
they are marked as non-interactive and as a subshell
*/
is_subshell=1; is_subshell=1;
is_interactive=1; is_interactive=0;
eval( (wchar_t *)b->buff, 0, TOP ); eval( (wchar_t *)b->buff, 0, TOP );
is_subshell=0;
is_interactive=1;
} }
/*
Restore interactivity flags
*/
is_subshell = was_subshell;
is_interactive = was_interactive;
if( b ) if( b )
{ {
sb_destroy( b ); sb_destroy( b );

View File

@ -61,6 +61,9 @@ typedef struct
} param1; } param1;
/**
The name of the event handler function
*/
const wchar_t *function_name; const wchar_t *function_name;
} }
event_t; event_t;

View File

@ -20,7 +20,7 @@ printf 'for instructions on how to use fish\n'
# Set exit message # Set exit message
# #
function fish_on_exit -d "Commands to execute when fish exits" function fish_on_exit -d "Commands to execute when fish exits" --on-process %self
echo Good bye echo Good bye
end end

6
main.c
View File

@ -284,11 +284,7 @@ int main( int argc, char **argv )
} }
} }
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
if( function_exists(L"fish_on_exit"))
{
eval( L"fish_on_exit", 0, TOP );
}
reader_pop_current_filename(); reader_pop_current_filename();

11
proc.c
View File

@ -482,12 +482,9 @@ static void format_job_info( const job_t *j, const wchar_t *status )
fwprintf (stdout, L"\n" ); fwprintf (stdout, L"\n" );
} }
static void fire_process_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; static event_t ev;
event_t e;
e.function_name=0;
ev.type=type; ev.type=type;
ev.param1.pid = pid; ev.param1.pid = pid;
@ -538,7 +535,7 @@ int job_reap( int interactive )
s = p->status; s = p->status;
fire_process_event( L"PROCESS_EXIT", EVENT_EXIT, p->pid, ( WIFSIGNALED(s)?-1:WEXITSTATUS( s )) ); proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, p->pid, ( WIFSIGNALED(s)?-1:WEXITSTATUS( s )) );
if( WIFSIGNALED(s) ) if( WIFSIGNALED(s) )
{ {
@ -596,8 +593,8 @@ int job_reap( int interactive )
found=1; found=1;
} }
} }
fire_process_event( L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0 ); proc_fire_event( L"JOB_EXIT", EVENT_EXIT, -j->pgid, 0 );
fire_process_event( L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0 ); proc_fire_event( L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0 );
job_free(j); job_free(j);
} }

5
proc.h
View File

@ -254,6 +254,11 @@ void proc_update_jiffies();
*/ */
void proc_sanity_check(); void proc_sanity_check();
/**
Send of an process/job exit event notification. This function is a conveniance wrapper around event_fire().
*/
void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status );
/* /*
Initializations Initializations
*/ */

View File

@ -2761,8 +2761,8 @@ wchar_t *reader_readline()
break; break;
} }
/* Move left*/ /* Move left*/
case R_BACKWARD_CHAR: case R_BACKWARD_CHAR:
if( data->buff_pos > 0 ) if( data->buff_pos > 0 )