diff options
author | axel <axel@liljencrantz.se> | 2005-10-12 05:23:43 +1000 |
---|---|---|
committer | axel <axel@liljencrantz.se> | 2005-10-12 05:23:43 +1000 |
commit | 838ba08eaa883026d6fb88cd65dde33b16a564fd (patch) | |
tree | 164ec92c2b27f82e7fced328e5f0922813645d00 /proc.c | |
parent | 0a4b983afa4137da9392b2bb198a02f6d1df38f7 (diff) |
Event handling and job reaping updates
darcs-hash:20051011192343-ac50b-aa3f5ae5e2b34d122f10e3b59ceb6fdd447f4ae3.gz
Diffstat (limited to 'proc.c')
-rw-r--r-- | proc.c | 85 |
1 files changed, 71 insertions, 14 deletions
@@ -47,6 +47,7 @@ Some of the code in this file is based on code from the Glibc manual. #include "env.h" #include "parser.h" #include "signal.h" +#include "event.h" /** Size of message buffer @@ -460,33 +461,82 @@ static void format_job_info( const job_t *j, const wchar_t *status ) fwprintf (stdout, L"\n" ); } -int job_do_notification() +static void fire_process_event( const wchar_t *msg, pid_t pid, int status ) +{ + static event_t ev; + static array_list_t event_arg; + static string_buffer_t event_pid, event_status; + static int init=0; + + event_t e; + + if( !init ) + { + al_init( &event_arg ); + sb_init( &event_pid ); + sb_init( &event_status ); + init=1; + } + + e.function_name=0; + + ev.type=EVENT_EXIT; + ev.pid = pid; + + al_push( &event_arg, msg ); + + sb_printf( &event_pid, L"%d", pid ); + al_push( &event_arg, event_pid.buff ); + + sb_printf( &event_status, L"%d", status ); + al_push( &event_arg, event_status.buff ); + + event_fire( &ev, &event_arg ); + al_truncate( &event_arg, 0 ); + sb_clear( &event_pid ); + sb_clear( &event_status ); +} + +int job_reap( int interactive ) { job_t *j, *jnext; int found=0; + static int locked = 0; + + locked++; + if( locked>1 ) + return; + for( j=first_job; j; j=jnext) { process_t *p; jnext = j->next; - - + + if( (!j->skip_notification) && (!interactive) ) + { + continue; + } + for( p=j->first_process; p; p=p->next ) { + int s; if( !p->completed ) continue; - if( p->type ) - continue; - + if( !p->pid ) + continue; - if( WIFSIGNALED(p->status) ) + fire_process_event( L"PROCESS_EXIT", p->pid, WEXITSTATUS( s ) ); + s = p->status; + + if( WIFSIGNALED(s) ) { /* Ignore signal SIGPIPE.We issue it ourselves to the pipe writer when the pipe reader dies. */ - if( WTERMSIG(p->status) != SIGPIPE ) + if( WTERMSIG(s) != SIGPIPE ) { int proc_is_job = ((p==j->first_process) && (p->next == 0)); if( proc_is_job ) @@ -519,40 +569,47 @@ int job_do_notification() */ p->status = 0; } - } + } } /* If all processes have completed, tell the user the job has completed and delete it from the active job list. */ - if( job_is_completed(j) ) { + if( job_is_completed( j ) ) + { if( !j->fg && !j->notified ) { if( !j->skip_notification ) { - format_job_info (j, L"ended"); + format_job_info( j, L"ended" ); found=1; } } job_free(j); + + fire_process_event( L"JOB_EXIT", -j->pgid, 0 ); } - else if(job_is_stopped (j) && !j->notified) { + else if( job_is_stopped( j ) && !j->notified ) + { /* Notify the user about newly stopped jobs. */ if( !j->skip_notification ) { - format_job_info(j, L"stopped"); + format_job_info( j, L"stopped" ); found=1; } j->notified = 1; } } + if( found ) fflush( stdout ); - return found; + + locked = 0; + return found; } |