From ee979cdd95acb1a2bfa8b02f67d5386d3c8af5e3 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 2 Nov 1999 17:36:20 +0000 Subject: Split some more stuff out of psignal.c. --- c/src/exec/posix/src/Makefile.in | 5 +- c/src/exec/posix/src/psignal.c | 236 +--------------------- c/src/exec/posix/src/psignalchecksignal.c | 90 +++++++++ c/src/exec/posix/src/psignalclearprocesssignals.c | 38 ++++ c/src/exec/posix/src/psignalclearsignals.c | 85 ++++++++ c/src/exec/posix/src/psignalsetprocesssignals.c | 38 ++++ c/src/exec/posix/src/psignalunblockthread.c | 89 ++++++++ cpukit/posix/src/psignal.c | 236 +--------------------- cpukit/posix/src/psignalchecksignal.c | 90 +++++++++ cpukit/posix/src/psignalclearprocesssignals.c | 38 ++++ cpukit/posix/src/psignalclearsignals.c | 85 ++++++++ cpukit/posix/src/psignalsetprocesssignals.c | 38 ++++ cpukit/posix/src/psignalunblockthread.c | 89 ++++++++ 13 files changed, 686 insertions(+), 471 deletions(-) create mode 100644 c/src/exec/posix/src/psignalchecksignal.c create mode 100644 c/src/exec/posix/src/psignalclearprocesssignals.c create mode 100644 c/src/exec/posix/src/psignalclearsignals.c create mode 100644 c/src/exec/posix/src/psignalsetprocesssignals.c create mode 100644 c/src/exec/posix/src/psignalunblockthread.c create mode 100644 cpukit/posix/src/psignalchecksignal.c create mode 100644 cpukit/posix/src/psignalclearprocesssignals.c create mode 100644 cpukit/posix/src/psignalclearsignals.c create mode 100644 cpukit/posix/src/psignalsetprocesssignals.c create mode 100644 cpukit/posix/src/psignalunblockthread.c diff --git a/c/src/exec/posix/src/Makefile.in b/c/src/exec/posix/src/Makefile.in index f724cc4e6a..c6d55c73e2 100644 --- a/c/src/exec/posix/src/Makefile.in +++ b/c/src/exec/posix/src/Makefile.in @@ -45,7 +45,10 @@ PTHREAD_C_PIECES = pthread pthreadsetcputime pthreadgetcputime \ pthreadattrgetinheritsched pthreadattrsetinheritsched \ pthreadattrgetscope pthreadattrsetscope -PSIGNAL_C_PIECES = psignal alarm kill killinfo pause pthreadkill \ +PSIGNAL_C_PIECES = psignal alarm kill killinfo pause \ + psignalclearprocesssignals psignalsetprocesssignals \ + psignalchecksignal psignalclearsignals \ + psignalunblockthread pthreadkill \ pthreadsigmask sigaction sigaddset sigdelset sigemptyset sigfillset \ sigismember sigpending sigprocmask sigqueue sigsuspend sigtimedwait \ sigwait sigwaitinfo signal_2 diff --git a/c/src/exec/posix/src/psignal.c b/c/src/exec/posix/src/psignal.c index 0d7d3a2e8c..28e1ee8319 100644 --- a/c/src/exec/posix/src/psignal.c +++ b/c/src/exec/posix/src/psignal.c @@ -98,243 +98,9 @@ Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ]; (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \ (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) -/*PAGE - * - * _POSIX_signals_Unblock_thread - */ - -/* XXX this routine could probably be cleaned up */ -boolean _POSIX_signals_Unblock_thread( - Thread_Control *the_thread, - int signo, - siginfo_t *info -) -{ - POSIX_API_Control *api; - sigset_t mask; - siginfo_t *the_info = NULL; - - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - - mask = signo_to_mask( signo ); - - /* - * Is the thread is specifically waiting for a signal? - */ - - if ( _States_Is_interruptible_signal( the_thread->current_state ) ) { - - if ( (the_thread->Wait.option & mask) || (~api->signals_blocked & mask) ) { - the_thread->Wait.return_code = EINTR; - - the_info = (siginfo_t *) the_thread->Wait.return_argument; - - if ( !info ) { - the_info->si_signo = signo; - the_info->si_code = SI_USER; - the_info->si_value.sival_int = 0; - } else { - *the_info = *info; - } - - _Thread_queue_Extract_with_proxy( the_thread ); - return TRUE; - } - - /* - * This should only be reached via pthread_kill(). - */ - - return FALSE; - } - - if ( ~api->signals_blocked & mask ) { - the_thread->do_post_task_switch_extension = TRUE; - - if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) { - the_thread->Wait.return_code = EINTR; - if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) ) - _Thread_queue_Extract_with_proxy( the_thread ); - else if ( _States_Is_delaying(the_thread->current_state)){ - if ( _Watchdog_Is_active( &the_thread->Timer ) ) - (void) _Watchdog_Remove( &the_thread->Timer ); - _Thread_Unblock( the_thread ); - } - } - } - return FALSE; - -} - -/*PAGE - * - * _POSIX_signals_Set_process_signals - */ - -void _POSIX_signals_Set_process_signals( - sigset_t mask -) -{ - ISR_Level level; - - _ISR_Disable( level ); - if ( !_POSIX_signals_Pending ) - _Thread_Do_post_task_switch_extension++; - _POSIX_signals_Pending |= mask; - _ISR_Enable( level ); -} - -/*PAGE - * - * _POSIX_signals_Clear_process_signals - */ - -void _POSIX_signals_Clear_process_signals( - sigset_t mask -) -{ - ISR_Level level; - - _ISR_Disable( level ); - _POSIX_signals_Pending &= ~mask; - if ( !_POSIX_signals_Pending ) - _Thread_Do_post_task_switch_extension--; - _ISR_Enable( level ); -} - -/*PAGE - * - * _POSIX_signals_Clear_signals - */ - -boolean _POSIX_signals_Clear_signals( - POSIX_API_Control *api, - int signo, - siginfo_t *info, - boolean is_global, - boolean check_blocked -) -{ - sigset_t mask; - sigset_t signals_blocked; - ISR_Level level; - boolean do_callout; - POSIX_signals_Siginfo_node *psiginfo; - - mask = signo_to_mask( signo ); - - do_callout = FALSE; - - /* set blocked signals based on if checking for them, SIGNAL_ALL_MASK - * insures that no signals are blocked and all are checked. - */ - - if ( check_blocked ) - signals_blocked = ~api->signals_blocked; - else - signals_blocked = SIGNAL_ALL_MASK; - - /* XXX this is not right for siginfo type signals yet */ - /* XXX since they can't be cleared the same way */ - - _ISR_Disable( level ); - if ( is_global ) { - if ( mask & (_POSIX_signals_Pending & signals_blocked) ) { - if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) { - psiginfo = (POSIX_signals_Siginfo_node *) - _Chain_Get_unprotected( &_POSIX_signals_Siginfo[ signo ] ); - if ( _Chain_Is_empty( &_POSIX_signals_Siginfo[ signo ] ) ) - _POSIX_signals_Clear_process_signals( mask ); - if ( psiginfo ) { - *info = psiginfo->Info; - _Chain_Append_unprotected( - &_POSIX_signals_Inactive_siginfo, - &psiginfo->Node - ); - } else - do_callout = FALSE; - } else - _POSIX_signals_Clear_process_signals( mask ); - do_callout = TRUE; - } - } else { - if ( mask & (api->signals_pending & signals_blocked) ) { - api->signals_pending &= ~mask; - do_callout = TRUE; - } - } - _ISR_Enable( level ); - return do_callout; -} - - -/*PAGE - * - * _POSIX_signals_Check_signal - */ - -boolean _POSIX_signals_Check_signal( - POSIX_API_Control *api, - int signo, - boolean is_global -) -{ - siginfo_t siginfo_struct; - sigset_t saved_signals_blocked; - - if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct, - is_global, TRUE ) ) - return FALSE; - - /* - * Since we made a union of these, only one test is necessary but this is - * safer. - */ - - assert( _POSIX_signals_Vectors[ signo ].sa_handler || - _POSIX_signals_Vectors[ signo ].sa_sigaction ); - - /* - * Just to prevent sending a signal which is currently being ignored. - */ - - if ( _POSIX_signals_Vectors[ signo ].sa_handler == SIG_IGN ) - return FALSE; - - /* - * Block the signals requested in sa_mask - */ - - saved_signals_blocked = api->signals_blocked; - api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask; - - /* Here, the signal handler function executes */ - - switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) { - case SA_SIGINFO: /* - * - * assert( is_global ); + * _POSIX_signals_Post_switch_extension */ - (*_POSIX_signals_Vectors[ signo ].sa_sigaction)( - signo, - &siginfo_struct, - NULL /* context is undefined per 1003.1b-1993, p. 66 */ - ); - break; - default: - (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo ); - break; - } - - /* - * Restore the previous set of blocked signals - */ - - api->signals_blocked = saved_signals_blocked; - - return TRUE; -} void _POSIX_signals_Post_switch_extension( Thread_Control *the_thread diff --git a/c/src/exec/posix/src/psignalchecksignal.c b/c/src/exec/posix/src/psignalchecksignal.c new file mode 100644 index 0000000000..f733994067 --- /dev/null +++ b/c/src/exec/posix/src/psignalchecksignal.c @@ -0,0 +1,90 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/*PAGE + * + * _POSIX_signals_Check_signal + */ + +boolean _POSIX_signals_Check_signal( + POSIX_API_Control *api, + int signo, + boolean is_global +) +{ + siginfo_t siginfo_struct; + sigset_t saved_signals_blocked; + + if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct, + is_global, TRUE ) ) + return FALSE; + + /* + * Since we made a union of these, only one test is necessary but this is + * safer. + */ + + assert( _POSIX_signals_Vectors[ signo ].sa_handler || + _POSIX_signals_Vectors[ signo ].sa_sigaction ); + + /* + * Just to prevent sending a signal which is currently being ignored. + */ + + if ( _POSIX_signals_Vectors[ signo ].sa_handler == SIG_IGN ) + return FALSE; + + /* + * Block the signals requested in sa_mask + */ + + saved_signals_blocked = api->signals_blocked; + api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask; + + /* Here, the signal handler function executes */ + + switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) { + case SA_SIGINFO: +/* + * + * assert( is_global ); + */ + (*_POSIX_signals_Vectors[ signo ].sa_sigaction)( + signo, + &siginfo_struct, + NULL /* context is undefined per 1003.1b-1993, p. 66 */ + ); + break; + default: + (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo ); + break; + } + + /* + * Restore the previous set of blocked signals + */ + + api->signals_blocked = saved_signals_blocked; + + return TRUE; +} + diff --git a/c/src/exec/posix/src/psignalclearprocesssignals.c b/c/src/exec/posix/src/psignalclearprocesssignals.c new file mode 100644 index 0000000000..e182045462 --- /dev/null +++ b/c/src/exec/posix/src/psignalclearprocesssignals.c @@ -0,0 +1,38 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _POSIX_signals_Clear_process_signals + */ + +void _POSIX_signals_Clear_process_signals( + sigset_t mask +) +{ + ISR_Level level; + + _ISR_Disable( level ); + _POSIX_signals_Pending &= ~mask; + if ( !_POSIX_signals_Pending ) + _Thread_Do_post_task_switch_extension--; + _ISR_Enable( level ); +} diff --git a/c/src/exec/posix/src/psignalclearsignals.c b/c/src/exec/posix/src/psignalclearsignals.c new file mode 100644 index 0000000000..4dc7d9cb02 --- /dev/null +++ b/c/src/exec/posix/src/psignalclearsignals.c @@ -0,0 +1,85 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _POSIX_signals_Clear_signals + */ + +boolean _POSIX_signals_Clear_signals( + POSIX_API_Control *api, + int signo, + siginfo_t *info, + boolean is_global, + boolean check_blocked +) +{ + sigset_t mask; + sigset_t signals_blocked; + ISR_Level level; + boolean do_callout; + POSIX_signals_Siginfo_node *psiginfo; + + mask = signo_to_mask( signo ); + + do_callout = FALSE; + + /* set blocked signals based on if checking for them, SIGNAL_ALL_MASK + * insures that no signals are blocked and all are checked. + */ + + if ( check_blocked ) + signals_blocked = ~api->signals_blocked; + else + signals_blocked = SIGNAL_ALL_MASK; + + /* XXX this is not right for siginfo type signals yet */ + /* XXX since they can't be cleared the same way */ + + _ISR_Disable( level ); + if ( is_global ) { + if ( mask & (_POSIX_signals_Pending & signals_blocked) ) { + if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) { + psiginfo = (POSIX_signals_Siginfo_node *) + _Chain_Get_unprotected( &_POSIX_signals_Siginfo[ signo ] ); + if ( _Chain_Is_empty( &_POSIX_signals_Siginfo[ signo ] ) ) + _POSIX_signals_Clear_process_signals( mask ); + if ( psiginfo ) { + *info = psiginfo->Info; + _Chain_Append_unprotected( + &_POSIX_signals_Inactive_siginfo, + &psiginfo->Node + ); + } else + do_callout = FALSE; + } else + _POSIX_signals_Clear_process_signals( mask ); + do_callout = TRUE; + } + } else { + if ( mask & (api->signals_pending & signals_blocked) ) { + api->signals_pending &= ~mask; + do_callout = TRUE; + } + } + _ISR_Enable( level ); + return do_callout; +} diff --git a/c/src/exec/posix/src/psignalsetprocesssignals.c b/c/src/exec/posix/src/psignalsetprocesssignals.c new file mode 100644 index 0000000000..469735aef1 --- /dev/null +++ b/c/src/exec/posix/src/psignalsetprocesssignals.c @@ -0,0 +1,38 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _POSIX_signals_Set_process_signals + */ + +void _POSIX_signals_Set_process_signals( + sigset_t mask +) +{ + ISR_Level level; + + _ISR_Disable( level ); + if ( !_POSIX_signals_Pending ) + _Thread_Do_post_task_switch_extension++; + _POSIX_signals_Pending |= mask; + _ISR_Enable( level ); +} diff --git a/c/src/exec/posix/src/psignalunblockthread.c b/c/src/exec/posix/src/psignalunblockthread.c new file mode 100644 index 0000000000..916ed4724e --- /dev/null +++ b/c/src/exec/posix/src/psignalunblockthread.c @@ -0,0 +1,89 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/*PAGE + * + * _POSIX_signals_Unblock_thread + */ + +/* XXX this routine could probably be cleaned up */ +boolean _POSIX_signals_Unblock_thread( + Thread_Control *the_thread, + int signo, + siginfo_t *info +) +{ + POSIX_API_Control *api; + sigset_t mask; + siginfo_t *the_info = NULL; + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + mask = signo_to_mask( signo ); + + /* + * Is the thread is specifically waiting for a signal? + */ + + if ( _States_Is_interruptible_signal( the_thread->current_state ) ) { + + if ( (the_thread->Wait.option & mask) || (~api->signals_blocked & mask) ) { + the_thread->Wait.return_code = EINTR; + + the_info = (siginfo_t *) the_thread->Wait.return_argument; + + if ( !info ) { + the_info->si_signo = signo; + the_info->si_code = SI_USER; + the_info->si_value.sival_int = 0; + } else { + *the_info = *info; + } + + _Thread_queue_Extract_with_proxy( the_thread ); + return TRUE; + } + + /* + * This should only be reached via pthread_kill(). + */ + + return FALSE; + } + + if ( ~api->signals_blocked & mask ) { + the_thread->do_post_task_switch_extension = TRUE; + + if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) { + the_thread->Wait.return_code = EINTR; + if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) ) + _Thread_queue_Extract_with_proxy( the_thread ); + else if ( _States_Is_delaying(the_thread->current_state)){ + if ( _Watchdog_Is_active( &the_thread->Timer ) ) + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + } + } + return FALSE; + +} diff --git a/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c index 0d7d3a2e8c..28e1ee8319 100644 --- a/cpukit/posix/src/psignal.c +++ b/cpukit/posix/src/psignal.c @@ -98,243 +98,9 @@ Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ]; (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \ (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) -/*PAGE - * - * _POSIX_signals_Unblock_thread - */ - -/* XXX this routine could probably be cleaned up */ -boolean _POSIX_signals_Unblock_thread( - Thread_Control *the_thread, - int signo, - siginfo_t *info -) -{ - POSIX_API_Control *api; - sigset_t mask; - siginfo_t *the_info = NULL; - - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - - mask = signo_to_mask( signo ); - - /* - * Is the thread is specifically waiting for a signal? - */ - - if ( _States_Is_interruptible_signal( the_thread->current_state ) ) { - - if ( (the_thread->Wait.option & mask) || (~api->signals_blocked & mask) ) { - the_thread->Wait.return_code = EINTR; - - the_info = (siginfo_t *) the_thread->Wait.return_argument; - - if ( !info ) { - the_info->si_signo = signo; - the_info->si_code = SI_USER; - the_info->si_value.sival_int = 0; - } else { - *the_info = *info; - } - - _Thread_queue_Extract_with_proxy( the_thread ); - return TRUE; - } - - /* - * This should only be reached via pthread_kill(). - */ - - return FALSE; - } - - if ( ~api->signals_blocked & mask ) { - the_thread->do_post_task_switch_extension = TRUE; - - if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) { - the_thread->Wait.return_code = EINTR; - if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) ) - _Thread_queue_Extract_with_proxy( the_thread ); - else if ( _States_Is_delaying(the_thread->current_state)){ - if ( _Watchdog_Is_active( &the_thread->Timer ) ) - (void) _Watchdog_Remove( &the_thread->Timer ); - _Thread_Unblock( the_thread ); - } - } - } - return FALSE; - -} - -/*PAGE - * - * _POSIX_signals_Set_process_signals - */ - -void _POSIX_signals_Set_process_signals( - sigset_t mask -) -{ - ISR_Level level; - - _ISR_Disable( level ); - if ( !_POSIX_signals_Pending ) - _Thread_Do_post_task_switch_extension++; - _POSIX_signals_Pending |= mask; - _ISR_Enable( level ); -} - -/*PAGE - * - * _POSIX_signals_Clear_process_signals - */ - -void _POSIX_signals_Clear_process_signals( - sigset_t mask -) -{ - ISR_Level level; - - _ISR_Disable( level ); - _POSIX_signals_Pending &= ~mask; - if ( !_POSIX_signals_Pending ) - _Thread_Do_post_task_switch_extension--; - _ISR_Enable( level ); -} - -/*PAGE - * - * _POSIX_signals_Clear_signals - */ - -boolean _POSIX_signals_Clear_signals( - POSIX_API_Control *api, - int signo, - siginfo_t *info, - boolean is_global, - boolean check_blocked -) -{ - sigset_t mask; - sigset_t signals_blocked; - ISR_Level level; - boolean do_callout; - POSIX_signals_Siginfo_node *psiginfo; - - mask = signo_to_mask( signo ); - - do_callout = FALSE; - - /* set blocked signals based on if checking for them, SIGNAL_ALL_MASK - * insures that no signals are blocked and all are checked. - */ - - if ( check_blocked ) - signals_blocked = ~api->signals_blocked; - else - signals_blocked = SIGNAL_ALL_MASK; - - /* XXX this is not right for siginfo type signals yet */ - /* XXX since they can't be cleared the same way */ - - _ISR_Disable( level ); - if ( is_global ) { - if ( mask & (_POSIX_signals_Pending & signals_blocked) ) { - if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) { - psiginfo = (POSIX_signals_Siginfo_node *) - _Chain_Get_unprotected( &_POSIX_signals_Siginfo[ signo ] ); - if ( _Chain_Is_empty( &_POSIX_signals_Siginfo[ signo ] ) ) - _POSIX_signals_Clear_process_signals( mask ); - if ( psiginfo ) { - *info = psiginfo->Info; - _Chain_Append_unprotected( - &_POSIX_signals_Inactive_siginfo, - &psiginfo->Node - ); - } else - do_callout = FALSE; - } else - _POSIX_signals_Clear_process_signals( mask ); - do_callout = TRUE; - } - } else { - if ( mask & (api->signals_pending & signals_blocked) ) { - api->signals_pending &= ~mask; - do_callout = TRUE; - } - } - _ISR_Enable( level ); - return do_callout; -} - - -/*PAGE - * - * _POSIX_signals_Check_signal - */ - -boolean _POSIX_signals_Check_signal( - POSIX_API_Control *api, - int signo, - boolean is_global -) -{ - siginfo_t siginfo_struct; - sigset_t saved_signals_blocked; - - if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct, - is_global, TRUE ) ) - return FALSE; - - /* - * Since we made a union of these, only one test is necessary but this is - * safer. - */ - - assert( _POSIX_signals_Vectors[ signo ].sa_handler || - _POSIX_signals_Vectors[ signo ].sa_sigaction ); - - /* - * Just to prevent sending a signal which is currently being ignored. - */ - - if ( _POSIX_signals_Vectors[ signo ].sa_handler == SIG_IGN ) - return FALSE; - - /* - * Block the signals requested in sa_mask - */ - - saved_signals_blocked = api->signals_blocked; - api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask; - - /* Here, the signal handler function executes */ - - switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) { - case SA_SIGINFO: /* - * - * assert( is_global ); + * _POSIX_signals_Post_switch_extension */ - (*_POSIX_signals_Vectors[ signo ].sa_sigaction)( - signo, - &siginfo_struct, - NULL /* context is undefined per 1003.1b-1993, p. 66 */ - ); - break; - default: - (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo ); - break; - } - - /* - * Restore the previous set of blocked signals - */ - - api->signals_blocked = saved_signals_blocked; - - return TRUE; -} void _POSIX_signals_Post_switch_extension( Thread_Control *the_thread diff --git a/cpukit/posix/src/psignalchecksignal.c b/cpukit/posix/src/psignalchecksignal.c new file mode 100644 index 0000000000..f733994067 --- /dev/null +++ b/cpukit/posix/src/psignalchecksignal.c @@ -0,0 +1,90 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/*PAGE + * + * _POSIX_signals_Check_signal + */ + +boolean _POSIX_signals_Check_signal( + POSIX_API_Control *api, + int signo, + boolean is_global +) +{ + siginfo_t siginfo_struct; + sigset_t saved_signals_blocked; + + if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct, + is_global, TRUE ) ) + return FALSE; + + /* + * Since we made a union of these, only one test is necessary but this is + * safer. + */ + + assert( _POSIX_signals_Vectors[ signo ].sa_handler || + _POSIX_signals_Vectors[ signo ].sa_sigaction ); + + /* + * Just to prevent sending a signal which is currently being ignored. + */ + + if ( _POSIX_signals_Vectors[ signo ].sa_handler == SIG_IGN ) + return FALSE; + + /* + * Block the signals requested in sa_mask + */ + + saved_signals_blocked = api->signals_blocked; + api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask; + + /* Here, the signal handler function executes */ + + switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) { + case SA_SIGINFO: +/* + * + * assert( is_global ); + */ + (*_POSIX_signals_Vectors[ signo ].sa_sigaction)( + signo, + &siginfo_struct, + NULL /* context is undefined per 1003.1b-1993, p. 66 */ + ); + break; + default: + (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo ); + break; + } + + /* + * Restore the previous set of blocked signals + */ + + api->signals_blocked = saved_signals_blocked; + + return TRUE; +} + diff --git a/cpukit/posix/src/psignalclearprocesssignals.c b/cpukit/posix/src/psignalclearprocesssignals.c new file mode 100644 index 0000000000..e182045462 --- /dev/null +++ b/cpukit/posix/src/psignalclearprocesssignals.c @@ -0,0 +1,38 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _POSIX_signals_Clear_process_signals + */ + +void _POSIX_signals_Clear_process_signals( + sigset_t mask +) +{ + ISR_Level level; + + _ISR_Disable( level ); + _POSIX_signals_Pending &= ~mask; + if ( !_POSIX_signals_Pending ) + _Thread_Do_post_task_switch_extension--; + _ISR_Enable( level ); +} diff --git a/cpukit/posix/src/psignalclearsignals.c b/cpukit/posix/src/psignalclearsignals.c new file mode 100644 index 0000000000..4dc7d9cb02 --- /dev/null +++ b/cpukit/posix/src/psignalclearsignals.c @@ -0,0 +1,85 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _POSIX_signals_Clear_signals + */ + +boolean _POSIX_signals_Clear_signals( + POSIX_API_Control *api, + int signo, + siginfo_t *info, + boolean is_global, + boolean check_blocked +) +{ + sigset_t mask; + sigset_t signals_blocked; + ISR_Level level; + boolean do_callout; + POSIX_signals_Siginfo_node *psiginfo; + + mask = signo_to_mask( signo ); + + do_callout = FALSE; + + /* set blocked signals based on if checking for them, SIGNAL_ALL_MASK + * insures that no signals are blocked and all are checked. + */ + + if ( check_blocked ) + signals_blocked = ~api->signals_blocked; + else + signals_blocked = SIGNAL_ALL_MASK; + + /* XXX this is not right for siginfo type signals yet */ + /* XXX since they can't be cleared the same way */ + + _ISR_Disable( level ); + if ( is_global ) { + if ( mask & (_POSIX_signals_Pending & signals_blocked) ) { + if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) { + psiginfo = (POSIX_signals_Siginfo_node *) + _Chain_Get_unprotected( &_POSIX_signals_Siginfo[ signo ] ); + if ( _Chain_Is_empty( &_POSIX_signals_Siginfo[ signo ] ) ) + _POSIX_signals_Clear_process_signals( mask ); + if ( psiginfo ) { + *info = psiginfo->Info; + _Chain_Append_unprotected( + &_POSIX_signals_Inactive_siginfo, + &psiginfo->Node + ); + } else + do_callout = FALSE; + } else + _POSIX_signals_Clear_process_signals( mask ); + do_callout = TRUE; + } + } else { + if ( mask & (api->signals_pending & signals_blocked) ) { + api->signals_pending &= ~mask; + do_callout = TRUE; + } + } + _ISR_Enable( level ); + return do_callout; +} diff --git a/cpukit/posix/src/psignalsetprocesssignals.c b/cpukit/posix/src/psignalsetprocesssignals.c new file mode 100644 index 0000000000..469735aef1 --- /dev/null +++ b/cpukit/posix/src/psignalsetprocesssignals.c @@ -0,0 +1,38 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _POSIX_signals_Set_process_signals + */ + +void _POSIX_signals_Set_process_signals( + sigset_t mask +) +{ + ISR_Level level; + + _ISR_Disable( level ); + if ( !_POSIX_signals_Pending ) + _Thread_Do_post_task_switch_extension++; + _POSIX_signals_Pending |= mask; + _ISR_Enable( level ); +} diff --git a/cpukit/posix/src/psignalunblockthread.c b/cpukit/posix/src/psignalunblockthread.c new file mode 100644 index 0000000000..916ed4724e --- /dev/null +++ b/cpukit/posix/src/psignalunblockthread.c @@ -0,0 +1,89 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/*PAGE + * + * _POSIX_signals_Unblock_thread + */ + +/* XXX this routine could probably be cleaned up */ +boolean _POSIX_signals_Unblock_thread( + Thread_Control *the_thread, + int signo, + siginfo_t *info +) +{ + POSIX_API_Control *api; + sigset_t mask; + siginfo_t *the_info = NULL; + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + mask = signo_to_mask( signo ); + + /* + * Is the thread is specifically waiting for a signal? + */ + + if ( _States_Is_interruptible_signal( the_thread->current_state ) ) { + + if ( (the_thread->Wait.option & mask) || (~api->signals_blocked & mask) ) { + the_thread->Wait.return_code = EINTR; + + the_info = (siginfo_t *) the_thread->Wait.return_argument; + + if ( !info ) { + the_info->si_signo = signo; + the_info->si_code = SI_USER; + the_info->si_value.sival_int = 0; + } else { + *the_info = *info; + } + + _Thread_queue_Extract_with_proxy( the_thread ); + return TRUE; + } + + /* + * This should only be reached via pthread_kill(). + */ + + return FALSE; + } + + if ( ~api->signals_blocked & mask ) { + the_thread->do_post_task_switch_extension = TRUE; + + if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) { + the_thread->Wait.return_code = EINTR; + if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) ) + _Thread_queue_Extract_with_proxy( the_thread ); + else if ( _States_Is_delaying(the_thread->current_state)){ + if ( _Watchdog_Is_active( &the_thread->Timer ) ) + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + } + } + return FALSE; + +} -- cgit v1.2.3