From 32e833f3319e279167e3c4cf50f73b5ff93e4d65 Mon Sep 17 00:00:00 2001 From: axel Date: Sun, 4 Dec 2005 05:46:18 +1000 Subject: [PATCH] Remove old event hooks, add more event handler documentation darcs-hash:20051203194618-ac50b-e90683cb69b19da789152164a89a34bf187fd4e4.gz --- builtin.c | 2 +- doc_src/doc.hdr | 36 ++++++++++++++++++++++++++---------- event.c | 18 ++++++++++++++---- event.h | 3 +++ init/fish_interactive.fish | 2 +- main.c | 6 +----- proc.c | 11 ++++------- proc.h | 5 +++++ reader.c | 4 ++-- 9 files changed, 57 insertions(+), 30 deletions(-) diff --git a/builtin.c b/builtin.c index d15e49a28..a9de36059 100644 --- a/builtin.c +++ b/builtin.c @@ -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 ); #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 sb_append2( sb_out, job_is_stopped(j)?L"stopped\t":L"running\t", // job_is_completed(j)?L"completed\t":L"unfinished\t", diff --git a/doc_src/doc.hdr b/doc_src/doc.hdr index fb2ace9db..0f47bd52b 100644 --- a/doc_src/doc.hdr +++ b/doc_src/doc.hdr @@ -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 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 -function hook \c fish_on_exit. If the \c -fish_on_exit is defined, it will be execute before the shell exits. +If you want to run a set of commands when \c fish exits, use an event +handler that is triggered by the exit of the shell: + +
function on_exit --on-process %self
+	echo fish is now exiting
+end
Universal variables are stored in the file .fishd.HOSTNAME, where HOSTNAME is the name of your @@ -841,15 +844,28 @@ end

-\subsection hooks Event hooks +\subsection event Event handlers -There are several special function names in fish. If a function is -given this name, it will be automatically called when a specific event -has occured. These functions are: +When defining a new function in fish, it is possible to make it into an +event handler, i.e. a function that is automatically run when a +specific event takes place. Events that can trigger a handler currently are: -- \c fish_on_exit, which is called before the shell exits -- \c fish_on_exec, which is called before interactively executing a command -- \c fish_on_return, which is called when control returns to the shell after interactively executing a command +* When a signal is delivered +* When a process or job exits +* When the value of a variable is updated + +Example: + +To specify a signal handler for the WINCH signal, write: + +
function --on-signal WINCH my_signal_handler
+	echo Got WINCH signal!
+end
+
+ +For more information on how to define new event handlers, see the +documentation for the function +command. \section issues Common issues with fish diff --git a/event.c b/event.c index 9ea680232..7685585b1 100644 --- a/event.c +++ b/event.c @@ -273,6 +273,9 @@ static void event_fire_internal( event_t *event, array_list_t *arguments ) int i, j; string_buffer_t *b=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 @@ -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 ); + /* + 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_interactive=1; - + is_interactive=0; 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 ) { sb_destroy( b ); diff --git a/event.h b/event.h index d1d08aa74..43d81a8d1 100644 --- a/event.h +++ b/event.h @@ -61,6 +61,9 @@ typedef struct } param1; + /** + The name of the event handler function + */ const wchar_t *function_name; } event_t; diff --git a/init/fish_interactive.fish b/init/fish_interactive.fish index 4c639fc0d..024ae74fe 100644 --- a/init/fish_interactive.fish +++ b/init/fish_interactive.fish @@ -20,7 +20,7 @@ printf 'for instructions on how to use fish\n' # 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 end diff --git a/main.c b/main.c index f9e8f3fc9..e4be0c642 100644 --- a/main.c +++ b/main.c @@ -284,11 +284,7 @@ int main( int argc, char **argv ) } } - - if( function_exists(L"fish_on_exit")) - { - eval( L"fish_on_exit", 0, TOP ); - } + proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res ); reader_pop_current_filename(); diff --git a/proc.c b/proc.c index 9bae4774d..fb6229da4 100644 --- a/proc.c +++ b/proc.c @@ -482,12 +482,9 @@ static void format_job_info( const job_t *j, const wchar_t *status ) 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; - event_t e; - - e.function_name=0; ev.type=type; ev.param1.pid = pid; @@ -538,7 +535,7 @@ int job_reap( int interactive ) 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) ) { @@ -596,8 +593,8 @@ int job_reap( int interactive ) found=1; } } - fire_process_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_EXIT, -j->pgid, 0 ); + proc_fire_event( L"JOB_EXIT", EVENT_JOB_ID, j->job_id, 0 ); job_free(j); } diff --git a/proc.h b/proc.h index 665ffc3da..368756741 100644 --- a/proc.h +++ b/proc.h @@ -254,6 +254,11 @@ void proc_update_jiffies(); */ 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 */ diff --git a/reader.c b/reader.c index 0f0482ce0..ec3aac449 100644 --- a/reader.c +++ b/reader.c @@ -2761,8 +2761,8 @@ wchar_t *reader_readline() break; } - - + + /* Move left*/ case R_BACKWARD_CHAR: if( data->buff_pos > 0 )