From 07d880f4bccd3d5f26fb729ca3fca5f6bed081d3 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Sun, 31 Jan 1999 20:45:31 +0000 Subject: Split psignal.c into many more files. This reduced the amount of object code that has to be loaded just for initializing the signal manager. --- cpukit/posix/include/rtems/posix/psignal.h | 93 +++ cpukit/posix/src/alarm.c | 48 ++ cpukit/posix/src/kill.c | 50 ++ cpukit/posix/src/killinfo.c | 328 ++++++++++ cpukit/posix/src/pause.c | 39 ++ cpukit/posix/src/psignal.c | 930 +---------------------------- cpukit/posix/src/pthreadkill.c | 79 +++ cpukit/posix/src/pthreadsigmask.c | 71 +++ cpukit/posix/src/sigaction.c | 85 +++ cpukit/posix/src/sigaddset.c | 40 ++ cpukit/posix/src/sigdelset.c | 45 ++ cpukit/posix/src/sigemptyset.c | 34 ++ cpukit/posix/src/sigfillset.c | 34 ++ cpukit/posix/src/sigismember.c | 43 ++ cpukit/posix/src/sigpending.c | 38 ++ cpukit/posix/src/sigprocmask.c | 37 ++ cpukit/posix/src/sigqueue.c | 31 + cpukit/posix/src/sigsuspend.c | 43 ++ cpukit/posix/src/sigtimedwait.c | 117 ++++ cpukit/posix/src/sigwait.c | 43 ++ cpukit/posix/src/sigwaitinfo.c | 31 + 21 files changed, 1341 insertions(+), 918 deletions(-) create mode 100644 cpukit/posix/src/alarm.c create mode 100644 cpukit/posix/src/kill.c create mode 100644 cpukit/posix/src/killinfo.c create mode 100644 cpukit/posix/src/pause.c create mode 100644 cpukit/posix/src/pthreadkill.c create mode 100644 cpukit/posix/src/pthreadsigmask.c create mode 100644 cpukit/posix/src/sigaction.c create mode 100644 cpukit/posix/src/sigaddset.c create mode 100644 cpukit/posix/src/sigdelset.c create mode 100644 cpukit/posix/src/sigemptyset.c create mode 100644 cpukit/posix/src/sigfillset.c create mode 100644 cpukit/posix/src/sigismember.c create mode 100644 cpukit/posix/src/sigpending.c create mode 100644 cpukit/posix/src/sigprocmask.c create mode 100644 cpukit/posix/src/sigqueue.c create mode 100644 cpukit/posix/src/sigsuspend.c create mode 100644 cpukit/posix/src/sigtimedwait.c create mode 100644 cpukit/posix/src/sigwait.c create mode 100644 cpukit/posix/src/sigwaitinfo.c (limited to 'cpukit/posix') diff --git a/cpukit/posix/include/rtems/posix/psignal.h b/cpukit/posix/include/rtems/posix/psignal.h index 4ecba1f41c..32e403a360 100644 --- a/cpukit/posix/include/rtems/posix/psignal.h +++ b/cpukit/posix/include/rtems/posix/psignal.h @@ -5,11 +5,67 @@ #ifndef __RTEMS_POSIX_SIGNALS_h #define __RTEMS_POSIX_SIGNALS_h +#include + +/* + * Currently 32 signals numbered 1-32 are defined + */ + +#define SIGNAL_EMPTY_MASK 0x00000000 +#define SIGNAL_ALL_MASK 0xffffffff + +#define signo_to_mask( _sig ) (1 << ((_sig) - 1)) + +#define is_valid_signo( _sig ) \ + ((_sig) >= 1 && (_sig) <= 32 ) + +#define _States_Is_interruptible_signal( _states ) \ + ( ((_states) & \ + (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \ + (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) + +#define SIGACTION_TERMINATE \ + { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Abormal_termination_handler} } +#define SIGACTION_IGNORE \ + { 0, SIGNAL_ALL_MASK, {SIG_IGN} } +#define SIGACTION_STOP \ + { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Stop_handler} } +#define SIGACTION_CONTINUE \ + { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Continue_handler} } + +#define SIG_ARRAY_MAX (SIGRTMAX + 1) + +/* + * Variables + */ + +extern sigset_t _POSIX_signals_Pending; + +extern struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ]; + +extern struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ]; + +extern Watchdog_Control _POSIX_signals_Alarm_timer; + +extern Thread_queue_Control _POSIX_signals_Wait_queue; + +extern Chain_Control _POSIX_signals_Inactive_siginfo; + +extern Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ]; + +/* + * POSIX internal siginfo structure + */ + typedef struct { Chain_Node Node; siginfo_t Info; } POSIX_signals_Siginfo_node; +/* + * Internal routines + */ + void _POSIX_signals_Manager_Initialization( int maximum_queued_signals ); @@ -18,5 +74,42 @@ void _POSIX_signals_Post_switch_extension( Thread_Control *the_thread ); +boolean _POSIX_signals_Unblock_thread( + Thread_Control *the_thread, + int signo, + siginfo_t *info +); + +boolean _POSIX_signals_Clear_signals( + POSIX_API_Control *api, + int signo, + siginfo_t *info, + boolean is_global, + boolean check_blocked +); + +int killinfo( + pid_t pid, + int sig, + const union sigval *value +); + +void _POSIX_signals_Set_process_signals( + sigset_t mask +); + +void _POSIX_signals_Set_process_signals( + sigset_t mask +); + +/* + * Default signal handlers + */ + +#define _POSIX_signals_Stop_handler NULL +#define _POSIX_signals_Continue_handler NULL + +void _POSIX_signals_Abormal_termination_handler( int signo ); + #endif /* end of file */ diff --git a/cpukit/posix/src/alarm.c b/cpukit/posix/src/alarm.c new file mode 100644 index 0000000000..a17fd04f4e --- /dev/null +++ b/cpukit/posix/src/alarm.c @@ -0,0 +1,48 @@ +/* + * 3.4.1 Schedule Alarm, P1003.1b-1993, p. 79 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include + +#include +#include +#include + +unsigned int alarm( + unsigned int seconds +) +{ + unsigned int remaining = 0; + Watchdog_Control *the_timer; + + the_timer = &_POSIX_signals_Alarm_timer; + + switch ( _Watchdog_Remove( the_timer ) ) { + case WATCHDOG_INACTIVE: + case WATCHDOG_BEING_INSERTED: + break; + + case WATCHDOG_ACTIVE: + case WATCHDOG_REMOVE_IT: + remaining = the_timer->initial - + (the_timer->stop_time - the_timer->start_time); + break; + } + + _Watchdog_Insert_seconds( the_timer, seconds ); + + return remaining; +} + diff --git a/cpukit/posix/src/kill.c b/cpukit/posix/src/kill.c new file mode 100644 index 0000000000..97cd17164d --- /dev/null +++ b/cpukit/posix/src/kill.c @@ -0,0 +1,50 @@ +/* + * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include + +#include +#include +#include + +int kill( + pid_t pid, + int sig +) +{ + return killinfo( pid, sig, NULL ); +} + +/* + * _kill_r + * + * This is the Newlib dependent reentrant version of kill(). + */ + +#if defined(RTEMS_NEWLIB) + +#include + +int _kill_r( + struct _reent *ptr, + pid_t pid, + int sig +) +{ + return kill( pid, sig ); +} +#endif + diff --git a/cpukit/posix/src/killinfo.c b/cpukit/posix/src/killinfo.c new file mode 100644 index 0000000000..442fddd3c7 --- /dev/null +++ b/cpukit/posix/src/killinfo.c @@ -0,0 +1,328 @@ +/* + * kill() support routine + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/*PAGE + * + * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68 + * + * NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS. + */ + +#define _POSIX_signals_Is_interested( _api, _mask ) \ + ( ~(_api)->signals_blocked & (_mask) ) + +int killinfo( + pid_t pid, + int sig, + const union sigval *value +) +{ + sigset_t mask; + POSIX_API_Control *api; + unsigned32 the_class; + unsigned32 index; + unsigned32 maximum; + Objects_Information *the_info; + Objects_Control **object_table; + Thread_Control *the_thread; + Thread_Control *interested_thread; + Priority_Control interested_priority; + Chain_Control *the_chain; + Chain_Node *the_node; + siginfo_t siginfo_struct; + siginfo_t *siginfo; + POSIX_signals_Siginfo_node *psiginfo; + + /* + * Only supported for the "calling process" (i.e. this node). + */ + + if( pid != getpid() ) + set_errno_and_return_minus_one( ESRCH ); + + /* + * Validate the signal passed if not 0. + */ + + if ( sig && !is_valid_signo(sig) ) + set_errno_and_return_minus_one( EINVAL ); + + /* + * If the signal is being ignored, then we are out of here. + */ + + if ( !sig || _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) + return 0; + + /* + * P1003.1c/Draft 10, p. 33 says that certain signals should always + * be directed to the executing thread such as those caused by hardware + * faults. + */ + + switch ( sig ) { + case SIGFPE: + case SIGILL: + case SIGSEGV: + return pthread_kill( pthread_self(), sig ); + default: + break; + } + + mask = signo_to_mask( sig ); + + /* + * Build up a siginfo structure + */ + + siginfo = &siginfo_struct; + siginfo->si_signo = sig; + siginfo->si_code = SI_USER; + if ( !value ) { + siginfo->si_value.sival_int = 0; + } else { + siginfo->si_value = *value; + } + + _Thread_Disable_dispatch(); + + /* + * Is the currently executing thread interested? If so then it will + * get it an execute it as soon as the dispatcher executes. + */ + + the_thread = _Thread_Executing; + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + if ( _POSIX_signals_Is_interested( api, mask ) ) { + goto process_it; + } + + /* + * Is an interested thread waiting for this signal (sigwait())? + */ + + /* XXX violation of visibility -- need to define thread queue support */ + + for( index=0 ; + index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ; + index++ ) { + + the_chain = &_POSIX_signals_Wait_queue.Queues.Priority[ index ]; + + for ( the_node = the_chain->first ; + !_Chain_Is_tail( the_chain, the_node ) ; + the_node = the_node->next ) { + + the_thread = (Thread_Control *)the_node; + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + if ((the_thread->Wait.option & mask) || (~api->signals_blocked & mask)) { + goto process_it; + } + + } + } + + /* + * Is any other thread interested? The highest priority interested + * thread is selected. In the event of a tie, then the following + * additional criteria is used: + * + * + ready thread over blocked + * + blocked on call interruptible by signal (can return EINTR) + * + blocked on call not interruptible by signal + * + * This looks at every thread in the system regardless of the creating API. + * + * NOTES: + * + * + rtems internal threads do not receive signals. + */ + + interested_thread = NULL; + interested_priority = PRIORITY_MAXIMUM + 1; + + for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS; + the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS; + the_class++ ) { + + if ( the_class == OBJECTS_INTERNAL_THREADS ) + continue; + + the_info = _Objects_Information_table[ the_class ]; + + if ( !the_info ) /* manager not installed */ + continue; + + maximum = the_info->maximum; + object_table = the_info->local_table; + + assert( object_table ); /* always at least 1 entry */ + + for ( index = 1 ; index <= maximum ; index++ ) { + the_thread = (Thread_Control *) object_table[ index ]; + + if ( !the_thread ) + continue; + + /* + * If this thread is of lower priority than the interested thread, + * go on to the next thread. + */ + + if ( the_thread->current_priority > interested_priority ) + continue; + + /* + * If this thread is not interested, then go on to the next thread. + */ + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + if ( !api || !_POSIX_signals_Is_interested( api, mask ) ) + continue; + + /* + * Now we know the thread under connsideration is interested. + * If the thread under consideration is of higher priority, then + * it becomes the interested thread. + */ + + if ( the_thread->current_priority < interested_priority ) { + interested_thread = the_thread; + interested_priority = the_thread->current_priority; + continue; + } + + /* + * Now the thread and the interested thread have the same priority. + * If the interested thread is ready, then we don't need to send it + * to a blocked thread. + */ + + if ( _States_Is_ready( interested_thread->current_state ) ) + continue; + + /* + * Now the interested thread is blocked. + * If the thread we are considering is not, the it becomes the + * interested thread. + */ + + if ( _States_Is_ready( the_thread->current_state ) ) { + interested_thread = the_thread; + interested_priority = the_thread->current_priority; + continue; + } + + /* + * Now we know both threads are blocked. + * If the interested thread is interruptible, then just use it. + */ + + /* XXX need a new states macro */ + if ( interested_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) + continue; + + /* + * Now both threads are blocked and the interested thread is not + * interruptible. + * If the thread under consideration is interruptible by a signal, + * then it becomes the interested thread. + */ + + /* XXX need a new states macro */ + if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) { + interested_thread = the_thread; + interested_priority = the_thread->current_priority; + } + } + } + + if ( interested_thread ) { + the_thread = interested_thread; + goto process_it; + } + + /* + * OK so no threads were interested right now. It will be left on the + * global pending until a thread receives it. The global set of threads + * can change interest in this signal in one of the following ways: + * + * + a thread is created with the signal unblocked, + * + pthread_sigmask() unblocks the signal, + * + sigprocmask() unblocks the signal, OR + * + sigaction() which changes the handler to SIG_IGN. + */ + + the_thread = NULL; + goto post_process_signal; + + /* + * We found a thread which was interested, so now we mark that this + * thread needs to do the post context switch extension so it can + * evaluate the signals pending. + */ + +process_it: + + the_thread->do_post_task_switch_extension = TRUE; + + /* + * Returns TRUE if the signal was synchronously given to a thread + * blocked waiting for the signal. + */ + + if ( _POSIX_signals_Unblock_thread( the_thread, sig, siginfo ) ) { + _Thread_Enable_dispatch(); + return 0; + } + +post_process_signal: + + /* + * We may have woken up a thread but we definitely need to post the + * signal to the process wide information set. + */ + + _POSIX_signals_Set_process_signals( mask ); + + if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) { + + psiginfo = (POSIX_signals_Siginfo_node *) + _Chain_Get( &_POSIX_signals_Inactive_siginfo ); + if ( !psiginfo ) + set_errno_and_return_minus_one( EAGAIN ); + + psiginfo->Info = *siginfo; + + _Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node ); + } + + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/pause.c b/cpukit/posix/src/pause.c new file mode 100644 index 0000000000..a39011bef8 --- /dev/null +++ b/cpukit/posix/src/pause.c @@ -0,0 +1,39 @@ +/* + * 3.4.2 Suspend Process Execution, P1003.1b-1993, p. 81 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include +#include + +#include +#include +#include + +/* + * 3.4.2 Suspend Process Execution, P1003.1b-1993, p. 81 + */ + +int pause( void ) +{ + sigset_t all_signals; + int status; + + (void) sigfillset( &all_signals ); + + status = sigtimedwait( &all_signals, NULL, NULL ); + + return status; +} + diff --git a/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c index 1450164021..555b55d580 100644 --- a/cpukit/posix/src/psignal.c +++ b/cpukit/posix/src/psignal.c @@ -18,40 +18,19 @@ #include #include -/* - * Currently 32 signals numbered 1-32 are defined - */ - -#define SIGNAL_EMPTY_MASK 0x00000000 -#define SIGNAL_ALL_MASK 0xffffffff - -#define signo_to_mask( _sig ) (1 << ((_sig) - 1)) - -#define is_valid_signo( _sig ) \ - ((_sig) >= 1 && (_sig) <= 32 ) - /*** PROCESS WIDE STUFF ****/ sigset_t _POSIX_signals_Pending; -void _POSIX_signals_Abormal_termination_handler( int signo ) -{ - exit( 1 ); -} +struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ]; -#define _POSIX_signals_Stop_handler NULL -#define _POSIX_signals_Continue_handler NULL +Watchdog_Control _POSIX_signals_Alarm_timer; -#define SIGACTION_TERMINATE \ - { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Abormal_termination_handler} } -#define SIGACTION_IGNORE \ - { 0, SIGNAL_ALL_MASK, {SIG_IGN} } -#define SIGACTION_STOP \ - { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Stop_handler} } -#define SIGACTION_CONTINUE \ - { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Continue_handler} } +Thread_queue_Control _POSIX_signals_Wait_queue; + +Chain_Control _POSIX_signals_Inactive_siginfo; +Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ]; -#define SIG_ARRAY_MAX (SIGRTMAX + 1) struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = { /* NO SIGNAL 0 */ SIGACTION_IGNORE, /* SIGHUP 1 */ SIGACTION_TERMINATE, @@ -89,24 +68,16 @@ struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = { /* SIGRTMAX 32 */ SIGACTION_IGNORE }; -struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ]; - -Watchdog_Control _POSIX_signals_Alarm_timer; - -Thread_queue_Control _POSIX_signals_Wait_queue; - -Chain_Control _POSIX_signals_Inactive_siginfo; -Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ]; - /*PAGE * - * XXX - move these + * _POSIX_signals_Abormal_termination_handler + * */ -#define _States_Is_interruptible_signal( _states ) \ - ( ((_states) & \ - (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \ - (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) +void _POSIX_signals_Abormal_termination_handler( int signo ) +{ + exit( 1 ); +} /*PAGE * @@ -484,880 +455,3 @@ void _POSIX_signals_Manager_Initialization( sizeof( POSIX_signals_Siginfo_node ) ); } - -/* - * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 - */ - -int sigemptyset( - sigset_t *set -) -{ - if ( !set ) - set_errno_and_return_minus_one( EINVAL ); - - *set = 0; - return 0; -} - -/* - * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 - */ - -int sigfillset( - sigset_t *set -) -{ - if ( !set ) - set_errno_and_return_minus_one( EINVAL ); - - *set = SIGNAL_ALL_MASK; - return 0; -} - -/* - * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 - */ - -int sigaddset( - sigset_t *set, - int signo -) -{ - if ( !set ) - set_errno_and_return_minus_one( EINVAL ); - - if ( !signo ) - return 0; - - if ( !is_valid_signo(signo) ) - set_errno_and_return_minus_one( EINVAL ); - - *set |= signo_to_mask(signo); - return 0; -} - -/* - * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 - */ - -int sigdelset( - sigset_t *set, - int signo -) -{ - if ( !set ) - set_errno_and_return_minus_one( EINVAL ); - - if ( !signo ) - return 0; - - if ( !is_valid_signo(signo) ) - set_errno_and_return_minus_one( EINVAL ); - - *set &= ~signo_to_mask(signo); - return 0; -} - -/* - * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 - */ - -int sigismember( - const sigset_t *set, - int signo -) -{ - if ( !set ) - set_errno_and_return_minus_one( EINVAL ); - - if ( !signo ) - return 0; - - if ( !is_valid_signo(signo) ) - set_errno_and_return_minus_one( EINVAL ); - - if ( *set & signo_to_mask(signo) ) - return 1; - - return 0; -} - -/* - * 3.3.4 Examine and Change Signal Action, P1003.1b-1993, p. 70 - */ - -int sigaction( - int sig, - const struct sigaction *act, - struct sigaction *oact -) -{ - ISR_Level level; - - if ( oact ) - *oact = _POSIX_signals_Vectors[ sig ]; - - if ( !sig ) - return 0; - - if ( !is_valid_signo(sig) ) - set_errno_and_return_minus_one( EINVAL ); - - /* - * Some signals cannot be ignored (P1003.1b-1993, pp. 70-72 and references. - * - * NOTE: Solaris documentation claims to "silently enforce" this which - * contradicts the POSIX specification. - */ - - if ( sig == SIGKILL ) - set_errno_and_return_minus_one( EINVAL ); - - /* - * Evaluate the new action structure and set the global signal vector - * appropriately. - */ - - if ( act ) { - - /* - * Unless the user is installing the default signal actions, then - * we can just copy the provided sigaction structure into the vectors. - */ - - _ISR_Disable( level ); - if ( act->sa_handler == SIG_DFL ) { - _POSIX_signals_Vectors[ sig ] = _POSIX_signals_Default_vectors[ sig ]; - } else { - _POSIX_signals_Clear_process_signals( signo_to_mask(sig) ); - _POSIX_signals_Vectors[ sig ] = *act; - } - _ISR_Enable( level ); - } - - /* - * No need to evaluate or dispatch because: - * - * + If we were ignoring the signal before, none could be pending - * now (signals not posted when SIG_IGN). - * + If we are now ignoring a signal that was previously pending, - * we clear the pending signal indicator. - */ - - return 0; -} - -/* - * 3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73 - * - * NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask(). - * - */ - -int sigprocmask( - int how, - const sigset_t *set, - sigset_t *oset -) -{ - /* - * P1003.1c/Draft 10, p. 38 maps sigprocmask to pthread_sigmask. - */ - - return pthread_sigmask( how, set, oset ); -} - -/* - * 3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73 - * - * NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask(). - */ - -int pthread_sigmask( - int how, - const sigset_t *set, - sigset_t *oset -) -{ - POSIX_API_Control *api; - - if ( !set && !oset ) - set_errno_and_return_minus_one( EINVAL ); - - api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; - - if ( oset ) - *oset = api->signals_blocked; - - if ( !set ) - return 0; - - switch ( how ) { - case SIG_BLOCK: - api->signals_blocked |= *set; - break; - case SIG_UNBLOCK: - api->signals_blocked &= ~*set; - break; - case SIG_SETMASK: - api->signals_blocked = *set; - break; - default: - set_errno_and_return_minus_one( EINVAL ); - } - - /* XXX are there critical section problems here? */ - - /* XXX evaluate the new set */ - - if ( ~api->signals_blocked & - (api->signals_pending | _POSIX_signals_Pending) ) { - _Thread_Executing->do_post_task_switch_extension = TRUE; - _Thread_Dispatch(); - } - - return 0; -} - -/* - * 3.3.6 Examine Pending Signals, P1003.1b-1993, p. 75 - */ - -int sigpending( - sigset_t *set -) -{ - POSIX_API_Control *api; - - if ( !set ) - set_errno_and_return_minus_one( EINVAL ); - - api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; - - *set = api->signals_pending | _POSIX_signals_Pending; - - return 0; -} - -/* - * 3.3.7 Wait for a Signal, P1003.1b-1993, p. 75 - */ - -int sigsuspend( - const sigset_t *sigmask -) -{ - sigset_t saved_signals_blocked; - sigset_t all_signals; - int status; - POSIX_API_Control *api; - - api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; - - status = sigprocmask( SIG_BLOCK, sigmask, &saved_signals_blocked ); - - (void) sigfillset( &all_signals ); - - status = sigtimedwait( &all_signals, NULL, NULL ); - - (void) sigprocmask( SIG_SETMASK, &saved_signals_blocked, NULL ); - - return status; -} - -/* - * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 - * - * NOTE: P1003.1c/D10, p. 39 adds sigwait(). - */ - -int sigwaitinfo( - const sigset_t *set, - siginfo_t *info -) -{ - return sigtimedwait( set, info, NULL ); -} - -/* - * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 - * - * NOTE: P1003.1c/D10, p. 39 adds sigwait(). - */ - -int _POSIX_signals_Get_highest( - sigset_t set -) -{ - int signo; - - for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) { - if ( set & signo_to_mask( signo ) ) - return signo; - } - -/* XXX - add __SIGFIRSTNOTRT or something like that to newlib siginfo.h */ - - for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) { - if ( set & signo_to_mask( signo ) ) - return signo; - } - - return 0; -} - -int sigtimedwait( - const sigset_t *set, - siginfo_t *info, - const struct timespec *timeout -) -{ - Thread_Control *the_thread; - POSIX_API_Control *api; - Watchdog_Interval interval; - siginfo_t signal_information; - siginfo_t *the_info; - int signo; - - the_info = ( info ) ? info : &signal_information; - - the_thread = _Thread_Executing; - - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - - /* - * What if they are already pending? - */ - - /* API signals pending? */ - - if ( *set & api->signals_pending ) { - /* XXX real info later */ - the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending ); - _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, - FALSE, FALSE ); - the_info->si_code = SI_USER; - the_info->si_value.sival_int = 0; - return the_info->si_signo; - } - - /* Process pending signals? */ - - if ( *set & _POSIX_signals_Pending) { - signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending ); - _POSIX_signals_Clear_signals( api, signo, the_info, TRUE, FALSE ); - - if ( !info ) { - the_info->si_signo = signo; - the_info->si_code = SI_USER; - the_info->si_value.sival_int = 0; - } - } - - interval = 0; - if ( timeout ) { - - if (timeout->tv_nsec < 0 || timeout->tv_nsec >= TOD_NANOSECONDS_PER_SECOND) - set_errno_and_return_minus_one( EINVAL ); - - interval = _POSIX_Timespec_to_interval( timeout ); - } - - the_info->si_signo = -1; - - _Thread_Disable_dispatch(); - the_thread->Wait.queue = &_POSIX_signals_Wait_queue; - the_thread->Wait.return_code = EINTR; - the_thread->Wait.option = *set; - the_thread->Wait.return_argument = (void *) the_info; - _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue ); - _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval ); - _Thread_Enable_dispatch(); - - errno = _Thread_Executing->Wait.return_code; - return the_info->si_signo; -} - -/* - * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 - * - * NOTE: P1003.1c/D10, p. 39 adds sigwait(). - */ - -int sigwait( - const sigset_t *set, - int *sig -) -{ - int status; - - status = sigtimedwait( set, NULL, NULL ); - - if ( status != -1 ) { - if ( sig ) - *sig = status; - return 0; - } - - return errno; -} - -/*PAGE - * - * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68 - * - * NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS. - */ - -#define _POSIX_signals_Is_interested( _api, _mask ) \ - ( ~(_api)->signals_blocked & (_mask) ) - -int killinfo( - pid_t pid, - int sig, - const union sigval *value -) -{ - sigset_t mask; - POSIX_API_Control *api; - unsigned32 the_class; - unsigned32 index; - unsigned32 maximum; - Objects_Information *the_info; - Objects_Control **object_table; - Thread_Control *the_thread; - Thread_Control *interested_thread; - Priority_Control interested_priority; - Chain_Control *the_chain; - Chain_Node *the_node; - siginfo_t siginfo_struct; - siginfo_t *siginfo; - POSIX_signals_Siginfo_node *psiginfo; - - /* - * Only supported for the "calling process" (i.e. this node). - */ - - if( pid != getpid() ) - set_errno_and_return_minus_one( ESRCH ); - - /* - * Validate the signal passed if not 0. - */ - - if ( sig && !is_valid_signo(sig) ) - set_errno_and_return_minus_one( EINVAL ); - - /* - * If the signal is being ignored, then we are out of here. - */ - - if ( !sig || _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) - return 0; - - /* - * P1003.1c/Draft 10, p. 33 says that certain signals should always - * be directed to the executing thread such as those caused by hardware - * faults. - */ - - switch ( sig ) { - case SIGFPE: - case SIGILL: - case SIGSEGV: - return pthread_kill( pthread_self(), sig ); - default: - break; - } - - mask = signo_to_mask( sig ); - - /* - * Build up a siginfo structure - */ - - siginfo = &siginfo_struct; - siginfo->si_signo = sig; - siginfo->si_code = SI_USER; - if ( !value ) { - siginfo->si_value.sival_int = 0; - } else { - siginfo->si_value = *value; - } - - _Thread_Disable_dispatch(); - - /* - * Is the currently executing thread interested? If so then it will - * get it an execute it as soon as the dispatcher executes. - */ - - the_thread = _Thread_Executing; - - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - if ( _POSIX_signals_Is_interested( api, mask ) ) { - goto process_it; - } - - /* - * Is an interested thread waiting for this signal (sigwait())? - */ - - /* XXX violation of visibility -- need to define thread queue support */ - - for( index=0 ; - index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ; - index++ ) { - - the_chain = &_POSIX_signals_Wait_queue.Queues.Priority[ index ]; - - for ( the_node = the_chain->first ; - !_Chain_Is_tail( the_chain, the_node ) ; - the_node = the_node->next ) { - - the_thread = (Thread_Control *)the_node; - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - - if ((the_thread->Wait.option & mask) || (~api->signals_blocked & mask)) { - goto process_it; - } - - } - } - - /* - * Is any other thread interested? The highest priority interested - * thread is selected. In the event of a tie, then the following - * additional criteria is used: - * - * + ready thread over blocked - * + blocked on call interruptible by signal (can return EINTR) - * + blocked on call not interruptible by signal - * - * This looks at every thread in the system regardless of the creating API. - * - * NOTES: - * - * + rtems internal threads do not receive signals. - */ - - interested_thread = NULL; - interested_priority = PRIORITY_MAXIMUM + 1; - - for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS; - the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS; - the_class++ ) { - - if ( the_class == OBJECTS_INTERNAL_THREADS ) - continue; - - the_info = _Objects_Information_table[ the_class ]; - - if ( !the_info ) /* manager not installed */ - continue; - - maximum = the_info->maximum; - object_table = the_info->local_table; - - assert( object_table ); /* always at least 1 entry */ - - for ( index = 1 ; index <= maximum ; index++ ) { - the_thread = (Thread_Control *) object_table[ index ]; - - if ( !the_thread ) - continue; - - /* - * If this thread is of lower priority than the interested thread, - * go on to the next thread. - */ - - if ( the_thread->current_priority > interested_priority ) - continue; - - /* - * If this thread is not interested, then go on to the next thread. - */ - - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - - if ( !api || !_POSIX_signals_Is_interested( api, mask ) ) - continue; - - /* - * Now we know the thread under connsideration is interested. - * If the thread under consideration is of higher priority, then - * it becomes the interested thread. - */ - - if ( the_thread->current_priority < interested_priority ) { - interested_thread = the_thread; - interested_priority = the_thread->current_priority; - continue; - } - - /* - * Now the thread and the interested thread have the same priority. - * If the interested thread is ready, then we don't need to send it - * to a blocked thread. - */ - - if ( _States_Is_ready( interested_thread->current_state ) ) - continue; - - /* - * Now the interested thread is blocked. - * If the thread we are considering is not, the it becomes the - * interested thread. - */ - - if ( _States_Is_ready( the_thread->current_state ) ) { - interested_thread = the_thread; - interested_priority = the_thread->current_priority; - continue; - } - - /* - * Now we know both threads are blocked. - * If the interested thread is interruptible, then just use it. - */ - - /* XXX need a new states macro */ - if ( interested_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) - continue; - - /* - * Now both threads are blocked and the interested thread is not - * interruptible. - * If the thread under consideration is interruptible by a signal, - * then it becomes the interested thread. - */ - - /* XXX need a new states macro */ - if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) { - interested_thread = the_thread; - interested_priority = the_thread->current_priority; - } - } - } - - if ( interested_thread ) { - the_thread = interested_thread; - goto process_it; - } - - /* - * OK so no threads were interested right now. It will be left on the - * global pending until a thread receives it. The global set of threads - * can change interest in this signal in one of the following ways: - * - * + a thread is created with the signal unblocked, - * + pthread_sigmask() unblocks the signal, - * + sigprocmask() unblocks the signal, OR - * + sigaction() which changes the handler to SIG_IGN. - */ - - the_thread = NULL; - goto post_process_signal; - - /* - * We found a thread which was interested, so now we mark that this - * thread needs to do the post context switch extension so it can - * evaluate the signals pending. - */ - -process_it: - - the_thread->do_post_task_switch_extension = TRUE; - - /* - * Returns TRUE if the signal was synchronously given to a thread - * blocked waiting for the signal. - */ - - if ( _POSIX_signals_Unblock_thread( the_thread, sig, siginfo ) ) { - _Thread_Enable_dispatch(); - return 0; - } - -post_process_signal: - - /* - * We may have woken up a thread but we definitely need to post the - * signal to the process wide information set. - */ - - _POSIX_signals_Set_process_signals( mask ); - - if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) { - - psiginfo = (POSIX_signals_Siginfo_node *) - _Chain_Get( &_POSIX_signals_Inactive_siginfo ); - if ( !psiginfo ) - set_errno_and_return_minus_one( EAGAIN ); - - psiginfo->Info = *siginfo; - - _Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node ); - } - - _Thread_Enable_dispatch(); - return 0; -} - -/*PAGE - * - * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68 - * - * NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS. - */ - -int kill( - pid_t pid, - int sig -) -{ - return killinfo( pid, sig, NULL ); -} - -/* - * _kill_r - * - * This is the Newlib dependent reentrant version of kill(). - */ - -#if defined(RTEMS_NEWLIB) - -#include - -int _kill_r( - struct _reent *ptr, - pid_t pid, - int sig -) -{ - return kill( pid, sig ); -} -#endif - -/* - * 3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78 - */ - -int sigqueue( - pid_t pid, - int signo, - const union sigval value -) -{ - return killinfo( pid, signo, &value ); -} - -/* - * 3.3.10 Send a Signal to a Thread, P1003.1c/D10, p. 43 - */ - -int pthread_kill( - pthread_t thread, - int sig -) -{ - POSIX_API_Control *api; - Thread_Control *the_thread; - Objects_Locations location; - - if ( sig && !is_valid_signo(sig) ) - set_errno_and_return_minus_one( EINVAL ); - - if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) - set_errno_and_return_minus_one( ENOSYS ); - - /* - * RTEMS does not support sending a siginfo signal to a specific thread. - */ - - the_thread = _POSIX_Threads_Get( thread, &location ); - switch ( location ) { - case OBJECTS_ERROR: - case OBJECTS_REMOTE: - set_errno_and_return_minus_one( ESRCH ); - case OBJECTS_LOCAL: - /* - * If sig == 0 then just validate arguments - */ - - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - - if ( sig ) { - - if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) { - _Thread_Enable_dispatch(); - return 0; - } - - /* XXX critical section */ - - api->signals_pending |= signo_to_mask( sig ); - - (void) _POSIX_signals_Unblock_thread( the_thread, sig, NULL ); - - the_thread->do_post_task_switch_extension = TRUE; - - if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) ) - _ISR_Signals_to_thread_executing = TRUE; - } - _Thread_Enable_dispatch(); - return 0; - } - - return POSIX_BOTTOM_REACHED(); -} - -/* - * 3.4.1 Schedule Alarm, P1003.1b-1993, p. 79 - */ - -Watchdog_Control _POSIX_signals_Alarm_timer; - -unsigned int alarm( - unsigned int seconds -) -{ - unsigned int remaining = 0; - Watchdog_Control *the_timer; - - the_timer = &_POSIX_signals_Alarm_timer; - - switch ( _Watchdog_Remove( the_timer ) ) { - case WATCHDOG_INACTIVE: - case WATCHDOG_BEING_INSERTED: - break; - - case WATCHDOG_ACTIVE: - case WATCHDOG_REMOVE_IT: - remaining = the_timer->initial - - (the_timer->stop_time - the_timer->start_time); - break; - } - - _Watchdog_Insert_seconds( the_timer, seconds ); - - return remaining; -} - -/* - * 3.4.2 Suspend Process Execution, P1003.1b-1993, p. 81 - */ - -int pause( void ) -{ - sigset_t all_signals; - int status; - - (void) sigfillset( &all_signals ); - - status = sigtimedwait( &all_signals, NULL, NULL ); - - return status; -} diff --git a/cpukit/posix/src/pthreadkill.c b/cpukit/posix/src/pthreadkill.c new file mode 100644 index 0000000000..652b3554a1 --- /dev/null +++ b/cpukit/posix/src/pthreadkill.c @@ -0,0 +1,79 @@ +/* + * 3.3.10 Send a Signal to a Thread, P1003.1c/D10, p. 43 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include + +#include +#include +#include +#include +#include + +int pthread_kill( + pthread_t thread, + int sig +) +{ + POSIX_API_Control *api; + Thread_Control *the_thread; + Objects_Locations location; + + if ( sig && !is_valid_signo(sig) ) + set_errno_and_return_minus_one( EINVAL ); + + if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) + set_errno_and_return_minus_one( ENOSYS ); + + /* + * RTEMS does not support sending a siginfo signal to a specific thread. + */ + + the_thread = _POSIX_Threads_Get( thread, &location ); + switch ( location ) { + case OBJECTS_ERROR: + case OBJECTS_REMOTE: + set_errno_and_return_minus_one( ESRCH ); + case OBJECTS_LOCAL: + /* + * If sig == 0 then just validate arguments + */ + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + if ( sig ) { + + if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) { + _Thread_Enable_dispatch(); + return 0; + } + + /* XXX critical section */ + + api->signals_pending |= signo_to_mask( sig ); + + (void) _POSIX_signals_Unblock_thread( the_thread, sig, NULL ); + + the_thread->do_post_task_switch_extension = TRUE; + + if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) ) + _ISR_Signals_to_thread_executing = TRUE; + } + _Thread_Enable_dispatch(); + return 0; + } + + return POSIX_BOTTOM_REACHED(); +} diff --git a/cpukit/posix/src/pthreadsigmask.c b/cpukit/posix/src/pthreadsigmask.c new file mode 100644 index 0000000000..1efede39c4 --- /dev/null +++ b/cpukit/posix/src/pthreadsigmask.c @@ -0,0 +1,71 @@ +/* + * 3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73 + * + * NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask(). + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include +#include + +#include +#include +#include +#include + +int pthread_sigmask( + int how, + const sigset_t *set, + sigset_t *oset +) +{ + POSIX_API_Control *api; + + if ( !set && !oset ) + set_errno_and_return_minus_one( EINVAL ); + + api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + if ( oset ) + *oset = api->signals_blocked; + + if ( !set ) + return 0; + + switch ( how ) { + case SIG_BLOCK: + api->signals_blocked |= *set; + break; + case SIG_UNBLOCK: + api->signals_blocked &= ~*set; + break; + case SIG_SETMASK: + api->signals_blocked = *set; + break; + default: + set_errno_and_return_minus_one( EINVAL ); + } + + /* XXX are there critical section problems here? */ + + /* XXX evaluate the new set */ + + if ( ~api->signals_blocked & + (api->signals_pending | _POSIX_signals_Pending) ) { + _Thread_Executing->do_post_task_switch_extension = TRUE; + _Thread_Dispatch(); + } + + return 0; +} diff --git a/cpukit/posix/src/sigaction.c b/cpukit/posix/src/sigaction.c new file mode 100644 index 0000000000..a2d709e8e7 --- /dev/null +++ b/cpukit/posix/src/sigaction.c @@ -0,0 +1,85 @@ +/* + * 3.3.4 Examine and Change Signal Action, P1003.1b-1993, p. 70 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include + +#include +#include +#include +#include +#include + +int sigaction( + int sig, + const struct sigaction *act, + struct sigaction *oact +) +{ + ISR_Level level; + + if ( oact ) + *oact = _POSIX_signals_Vectors[ sig ]; + + if ( !sig ) + return 0; + + if ( !is_valid_signo(sig) ) + set_errno_and_return_minus_one( EINVAL ); + + /* + * Some signals cannot be ignored (P1003.1b-1993, pp. 70-72 and references. + * + * NOTE: Solaris documentation claims to "silently enforce" this which + * contradicts the POSIX specification. + */ + + if ( sig == SIGKILL ) + set_errno_and_return_minus_one( EINVAL ); + + /* + * Evaluate the new action structure and set the global signal vector + * appropriately. + */ + + if ( act ) { + + /* + * Unless the user is installing the default signal actions, then + * we can just copy the provided sigaction structure into the vectors. + */ + + _ISR_Disable( level ); + if ( act->sa_handler == SIG_DFL ) { + _POSIX_signals_Vectors[ sig ] = _POSIX_signals_Default_vectors[ sig ]; + } else { + _POSIX_signals_Clear_process_signals( signo_to_mask(sig) ); + _POSIX_signals_Vectors[ sig ] = *act; + } + _ISR_Enable( level ); + } + + /* + * No need to evaluate or dispatch because: + * + * + If we were ignoring the signal before, none could be pending + * now (signals not posted when SIG_IGN). + * + If we are now ignoring a signal that was previously pending, + * we clear the pending signal indicator. + */ + + return 0; +} + diff --git a/cpukit/posix/src/sigaddset.c b/cpukit/posix/src/sigaddset.c new file mode 100644 index 0000000000..7e8058781f --- /dev/null +++ b/cpukit/posix/src/sigaddset.c @@ -0,0 +1,40 @@ +/* + * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include + +#include +#include +#include +#include + +int sigaddset( + sigset_t *set, + int signo +) +{ + if ( !set ) + set_errno_and_return_minus_one( EINVAL ); + + if ( !signo ) + return 0; + + if ( !is_valid_signo(signo) ) + set_errno_and_return_minus_one( EINVAL ); + + *set |= signo_to_mask(signo); + return 0; +} diff --git a/cpukit/posix/src/sigdelset.c b/cpukit/posix/src/sigdelset.c new file mode 100644 index 0000000000..c16449c287 --- /dev/null +++ b/cpukit/posix/src/sigdelset.c @@ -0,0 +1,45 @@ +/* + * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include + +#include +#include +#include +#include + +/* + * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 + */ + +int sigdelset( + sigset_t *set, + int signo +) +{ + if ( !set ) + set_errno_and_return_minus_one( EINVAL ); + + if ( !signo ) + return 0; + + if ( !is_valid_signo(signo) ) + set_errno_and_return_minus_one( EINVAL ); + + *set &= ~signo_to_mask(signo); + return 0; +} + diff --git a/cpukit/posix/src/sigemptyset.c b/cpukit/posix/src/sigemptyset.c new file mode 100644 index 0000000000..653a840d91 --- /dev/null +++ b/cpukit/posix/src/sigemptyset.c @@ -0,0 +1,34 @@ +/* + * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include + +#include +#include +#include +#include + +int sigemptyset( + sigset_t *set +) +{ + if ( !set ) + set_errno_and_return_minus_one( EINVAL ); + + *set = 0; + return 0; +} + diff --git a/cpukit/posix/src/sigfillset.c b/cpukit/posix/src/sigfillset.c new file mode 100644 index 0000000000..9ccef1a201 --- /dev/null +++ b/cpukit/posix/src/sigfillset.c @@ -0,0 +1,34 @@ +/* + * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include + +#include +#include +#include +#include + +int sigfillset( + sigset_t *set +) +{ + if ( !set ) + set_errno_and_return_minus_one( EINVAL ); + + *set = SIGNAL_ALL_MASK; + return 0; +} + diff --git a/cpukit/posix/src/sigismember.c b/cpukit/posix/src/sigismember.c new file mode 100644 index 0000000000..f98730a0d5 --- /dev/null +++ b/cpukit/posix/src/sigismember.c @@ -0,0 +1,43 @@ +/* + * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include + +#include +#include +#include +#include + +int sigismember( + const sigset_t *set, + int signo +) +{ + if ( !set ) + set_errno_and_return_minus_one( EINVAL ); + + if ( !signo ) + return 0; + + if ( !is_valid_signo(signo) ) + set_errno_and_return_minus_one( EINVAL ); + + if ( *set & signo_to_mask(signo) ) + return 1; + + return 0; +} + diff --git a/cpukit/posix/src/sigpending.c b/cpukit/posix/src/sigpending.c new file mode 100644 index 0000000000..49b34c9c46 --- /dev/null +++ b/cpukit/posix/src/sigpending.c @@ -0,0 +1,38 @@ +/* + * 3.3.6 Examine Pending Signals, P1003.1b-1993, p. 75 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include + +#include +#include +#include +#include + +int sigpending( + sigset_t *set +) +{ + POSIX_API_Control *api; + + if ( !set ) + set_errno_and_return_minus_one( EINVAL ); + + api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + *set = api->signals_pending | _POSIX_signals_Pending; + + return 0; +} diff --git a/cpukit/posix/src/sigprocmask.c b/cpukit/posix/src/sigprocmask.c new file mode 100644 index 0000000000..dcbbcfca4f --- /dev/null +++ b/cpukit/posix/src/sigprocmask.c @@ -0,0 +1,37 @@ +/* + * 3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73 + * + * NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask(). + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include +#include + +#include +#include +#include + +int sigprocmask( + int how, + const sigset_t *set, + sigset_t *oset +) +{ + /* + * P1003.1c/Draft 10, p. 38 maps sigprocmask to pthread_sigmask. + */ + + return pthread_sigmask( how, set, oset ); +} diff --git a/cpukit/posix/src/sigqueue.c b/cpukit/posix/src/sigqueue.c new file mode 100644 index 0000000000..e90cf8789f --- /dev/null +++ b/cpukit/posix/src/sigqueue.c @@ -0,0 +1,31 @@ +/* + * 3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include + +#include +#include +#include + +int sigqueue( + pid_t pid, + int signo, + const union sigval value +) +{ + return killinfo( pid, signo, &value ); +} + diff --git a/cpukit/posix/src/sigsuspend.c b/cpukit/posix/src/sigsuspend.c new file mode 100644 index 0000000000..beed3af5db --- /dev/null +++ b/cpukit/posix/src/sigsuspend.c @@ -0,0 +1,43 @@ +/* + * 3.3.7 Wait for a Signal, P1003.1b-1993, p. 75 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include + +#include +#include +#include + +int sigsuspend( + const sigset_t *sigmask +) +{ + sigset_t saved_signals_blocked; + sigset_t all_signals; + int status; + POSIX_API_Control *api; + + api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + status = sigprocmask( SIG_BLOCK, sigmask, &saved_signals_blocked ); + + (void) sigfillset( &all_signals ); + + status = sigtimedwait( &all_signals, NULL, NULL ); + + (void) sigprocmask( SIG_SETMASK, &saved_signals_blocked, NULL ); + + return status; +} diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c new file mode 100644 index 0000000000..bb35dd30d7 --- /dev/null +++ b/cpukit/posix/src/sigtimedwait.c @@ -0,0 +1,117 @@ +/* + * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include +#include + +#include +#include +#include +#include +#include + +int _POSIX_signals_Get_highest( + sigset_t set +) +{ + int signo; + + for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) { + if ( set & signo_to_mask( signo ) ) + return signo; + } + +/* XXX - add __SIGFIRSTNOTRT or something like that to newlib siginfo.h */ + + for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) { + if ( set & signo_to_mask( signo ) ) + return signo; + } + + return 0; +} + +int sigtimedwait( + const sigset_t *set, + siginfo_t *info, + const struct timespec *timeout +) +{ + Thread_Control *the_thread; + POSIX_API_Control *api; + Watchdog_Interval interval; + siginfo_t signal_information; + siginfo_t *the_info; + int signo; + + the_info = ( info ) ? info : &signal_information; + + the_thread = _Thread_Executing; + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + /* + * What if they are already pending? + */ + + /* API signals pending? */ + + if ( *set & api->signals_pending ) { + /* XXX real info later */ + the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending ); + _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, + FALSE, FALSE ); + the_info->si_code = SI_USER; + the_info->si_value.sival_int = 0; + return the_info->si_signo; + } + + /* Process pending signals? */ + + if ( *set & _POSIX_signals_Pending) { + signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending ); + _POSIX_signals_Clear_signals( api, signo, the_info, TRUE, FALSE ); + + if ( !info ) { + the_info->si_signo = signo; + the_info->si_code = SI_USER; + the_info->si_value.sival_int = 0; + } + } + + interval = 0; + if ( timeout ) { + + if (timeout->tv_nsec < 0 || timeout->tv_nsec >= TOD_NANOSECONDS_PER_SECOND) + set_errno_and_return_minus_one( EINVAL ); + + interval = _POSIX_Timespec_to_interval( timeout ); + } + + the_info->si_signo = -1; + + _Thread_Disable_dispatch(); + the_thread->Wait.queue = &_POSIX_signals_Wait_queue; + the_thread->Wait.return_code = EINTR; + the_thread->Wait.option = *set; + the_thread->Wait.return_argument = (void *) the_info; + _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue ); + _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval ); + _Thread_Enable_dispatch(); + + errno = _Thread_Executing->Wait.return_code; + return the_info->si_signo; +} diff --git a/cpukit/posix/src/sigwait.c b/cpukit/posix/src/sigwait.c new file mode 100644 index 0000000000..d0f026fb40 --- /dev/null +++ b/cpukit/posix/src/sigwait.c @@ -0,0 +1,43 @@ +/* + * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 + * + * NOTE: P1003.1c/D10, p. 39 adds sigwait(). + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include +#include + +#include +#include +#include + +int sigwait( + const sigset_t *set, + int *sig +) +{ + int status; + + status = sigtimedwait( set, NULL, NULL ); + + if ( status != -1 ) { + if ( sig ) + *sig = status; + return 0; + } + + return errno; +} + diff --git a/cpukit/posix/src/sigwaitinfo.c b/cpukit/posix/src/sigwaitinfo.c new file mode 100644 index 0000000000..ba9cd45c87 --- /dev/null +++ b/cpukit/posix/src/sigwaitinfo.c @@ -0,0 +1,31 @@ +/* + * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 + * + * NOTE: P1003.1c/D10, p. 39 adds sigwait(). + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include + +#include +#include +#include + +int sigwaitinfo( + const sigset_t *set, + siginfo_t *info +) +{ + return sigtimedwait( set, info, NULL ); +} + -- cgit v1.2.3