summaryrefslogtreecommitdiffstats
path: root/cpukit/posix
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1996-06-10 20:47:23 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1996-06-10 20:47:23 +0000
commitfdec30ba62ee920593806e4dbbe97c9152cacafe (patch)
treecb86ea63fcf716f5664270e2d79991bb2e5943fc /cpukit/posix
parent*** empty log message *** (diff)
downloadrtems-fdec30ba62ee920593806e4dbbe97c9152cacafe.tar.bz2
first attempt at the routine which vectors signals.
Diffstat (limited to 'cpukit/posix')
-rw-r--r--cpukit/posix/src/psignal.c336
-rw-r--r--cpukit/posix/src/pthread.c4
2 files changed, 328 insertions, 12 deletions
diff --git a/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c
index 7988e800e5..36f0583ddf 100644
--- a/cpukit/posix/src/psignal.c
+++ b/cpukit/posix/src/psignal.c
@@ -7,9 +7,11 @@
#include <signal.h>
#include <rtems/system.h>
+#include <rtems/score/isr.h>
#include <rtems/score/thread.h>
#include <rtems/posix/seterr.h>
#include <rtems/posix/threadsup.h>
+#include <rtems/posix/pthread.h>
/*
* Currently 32 signals numbered 1-32 are defined
@@ -21,14 +23,185 @@
#define signo_to_mask( _sig ) (1 << ((_sig) - 1))
#define is_valid_signo( _sig ) \
- ((signo_to_mask(_sig) & SIGNAL_ALL_MASK) != 0 )
+ ((_sig) >= 1 && (_sig) <= 32 )
/*** PROCESS WIDE STUFF ****/
-sigset_t _POSIX_signals_Blocked = SIGNAL_EMPTY_MASK;
-sigset_t _POSIX_signals_Pending = SIGNAL_EMPTY_MASK;
+sigset_t _POSIX_signals_Pending;
+sigset_t _POSIX_signals_Ignored;
+
+#define _POSIX_signals_Abormal_termination_handler NULL
+#define _POSIX_signals_Stop_handler NULL
+#define _POSIX_signals_Continue_handler NULL
+
+#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)
+struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = {
+ /* NO SIGNAL 0 */ SIGACTION_IGNORE,
+ /* SIGABRT */ SIGACTION_TERMINATE,
+ /* SIGALRM */ SIGACTION_TERMINATE,
+ /* SIGFPE */ SIGACTION_TERMINATE,
+ /* SIGHUP */ SIGACTION_TERMINATE,
+ /* SIGILL */ SIGACTION_TERMINATE,
+ /* SIGINT */ SIGACTION_TERMINATE,
+ /* SIGKILL */ SIGACTION_TERMINATE,
+ /* SIGPIPE */ SIGACTION_TERMINATE,
+ /* SIGQUIT */ SIGACTION_TERMINATE,
+ /* SIGSEGV */ SIGACTION_TERMINATE,
+ /* SIGTERM */ SIGACTION_TERMINATE,
+ /* SIGUSR1 */ SIGACTION_TERMINATE,
+ /* SIGUSR2 */ SIGACTION_TERMINATE,
+ /* SIGCHLD */ SIGACTION_IGNORE,
+ /* SIGCONT */ SIGACTION_CONTINUE,
+ /* SIGSTOP */ SIGACTION_STOP,
+ /* SIGTSTP */ SIGACTION_STOP,
+ /* SIGTTIN */ SIGACTION_STOP,
+ /* SIGTTOU */ SIGACTION_STOP,
+ /* SIGBUS */ SIGACTION_TERMINATE,
+ /* SIGRTMIN 21 */ SIGACTION_IGNORE,
+ /* SIGRT 22 */ SIGACTION_IGNORE,
+ /* SIGRT 23 */ SIGACTION_IGNORE,
+ /* SIGRT 24 */ SIGACTION_IGNORE,
+ /* SIGRT 25 */ SIGACTION_IGNORE,
+ /* SIGRT 26 */ SIGACTION_IGNORE,
+ /* SIGRT 27 */ SIGACTION_IGNORE,
+ /* SIGRT 28 */ SIGACTION_IGNORE,
+ /* SIGRT 29 */ SIGACTION_IGNORE,
+ /* SIGRT 30 */ SIGACTION_IGNORE,
+ /* SIGRT 31 */ SIGACTION_IGNORE,
+ /* SIGRTMAX 32 */ SIGACTION_IGNORE
+};
+
+struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ];
+
+Watchdog_Control _POSIX_signals_Alarm_timer;
+
+typedef struct {
+ Chain_Node Node;
+ siginfo_t Info;
+} POSIX_signals_Siginfo_node;
+
+Chain_Control _POSIX_signals_Inactive_siginfo;
+Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ];
-struct sigaction _POSIX_signals_Vectors[ SIGRTMAX ];
+/*PAGE
+ *
+ * XXX
+ */
+
+boolean _POSIX_signals_Check_signal(
+ POSIX_API_Control *api,
+ int signo,
+ boolean is_global
+)
+{
+ sigset_t mask;
+ ISR_Level level;
+ boolean do_callout;
+ siginfo_t *siginfo = NULL; /* really needs to be set below */
+ siginfo_t siginfo_struct;
+
+ mask = signo_to_mask( signo );
+
+ do_callout = FALSE;
+
+ _ISR_Disable( level );
+ if ( is_global ) {
+ ;
+ /* XXX check right place for thread versus global */
+ } else {
+ if ( mask & (api->signals_pending & ~api->signals_blocked ) ) {
+ api->signals_pending &= ~mask;
+ do_callout = TRUE;
+ }
+ }
+ _ISR_Enable( level );
+
+ if ( !do_callout )
+ return FALSE;
+
+ switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) {
+ case SA_SIGINFO:
+ assert( 0 ); /* XXX we haven't completely implemented this yet */
+ if ( !is_global ) {
+ siginfo = &siginfo_struct;
+ siginfo->si_signo = signo;
+ siginfo->si_code = SI_USER;
+ siginfo->si_value.sival_int = 0;
+ }
+ (*_POSIX_signals_Vectors[ signo ].sa_sigaction)(
+ signo,
+ siginfo,
+ NULL /* context is undefined per 1003.1b-1993, p. 66 */
+ );
+ break;
+ default:
+ (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo );
+ break;
+ }
+ return TRUE;
+}
+
+void _POSIX_signals_Run_Them(
+ Thread_Control *the_thread
+)
+{
+ POSIX_API_Control *api;
+ int signo;
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ /*
+ * If we invoke any user code, there is the possibility that
+ * a new signal has been posted that we should process.
+ */
+
+/* XXX somewhere we need to see if all pending signals are gone and clear */
+/* XXX do_post_switch_extension */
+
+restart:
+ for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
+
+ if ( _POSIX_signals_Check_signal( api, signo, FALSE ) )
+ goto restart;
+
+ if ( _POSIX_signals_Check_signal( api, signo, TRUE ) )
+ goto restart;
+
+ }
+
+ for ( signo = SIGABRT ; signo <= SIGBUS ; signo++ ) {
+
+ if ( _POSIX_signals_Check_signal( api, signo, FALSE ) )
+ goto restart;
+
+ if ( _POSIX_signals_Check_signal( api, signo, TRUE ) )
+ goto restart;
+
+ }
+
+}
+
+/*PAGE
+ *
+ * _POSIX_signals_Alarm_TSR
+ */
+
+void _POSIX_signals_Alarm_TSR(
+ Objects_Id id,
+ void *argument
+)
+{
+ kill( getpid(), SIGALRM );
+}
/*PAGE
*
@@ -37,7 +210,57 @@ struct sigaction _POSIX_signals_Vectors[ SIGRTMAX ];
void _POSIX_signals_Manager_Initialization( void )
{
- /* XXX install default actions for all vectors */
+ unsigned32 signo;
+
+ /*
+ * Insure we have the same number of vectors and default vector entries
+ */
+
+ assert(
+ sizeof(_POSIX_signals_Vectors) == sizeof(_POSIX_signals_Default_vectors)
+ );
+
+ memcpy(
+ _POSIX_signals_Vectors,
+ _POSIX_signals_Default_vectors,
+ sizeof( _POSIX_signals_Vectors )
+ );
+
+ /*
+ * Initialize the set of pending signals for the entire process
+ */
+
+ sigemptyset( &_POSIX_signals_Pending );
+
+ /*
+ * Calculate the mask for the set of signals which are being ignored.
+ */
+
+ sigemptyset( &_POSIX_signals_Ignored );
+
+ for ( signo=1 ; signo<= SIGRTMAX ; signo++ )
+ if ( _POSIX_signals_Default_vectors[ signo ].sa_handler == SIG_IGN )
+ sigaddset( &_POSIX_signals_Ignored, signo );
+
+ /*
+ * Initialize the timer used to implement alarm().
+ */
+
+ _Watchdog_Initialize(
+ &_POSIX_signals_Alarm_timer,
+ _POSIX_signals_Alarm_TSR,
+ 0,
+ NULL
+ );
+
+ /*
+ * XXX Allocate the siginfo pools.
+ */
+
+ for ( signo=1 ; signo<= SIGRTMAX ; signo++ )
+ _Chain_Initialize_empty( &_POSIX_signals_Siginfo[ signo ] );
+
+ /* XXX especially the inactive pool */
}
/*
@@ -149,6 +372,7 @@ int sigaction(
*oact = _POSIX_signals_Vectors[ sig ];
/* XXX need to interpret some stuff here */
+ /* XXX some signals cannot be ignored */
_POSIX_signals_Vectors[ sig ] = *act;
@@ -188,6 +412,9 @@ int pthread_sigmask(
)
{
POSIX_API_Control *api;
+ boolean evaluate_signals;
+
+/* XXX some signals can not be ignored */
if ( !set && !oset )
set_errno_and_return_minus_one( EFAULT );
@@ -200,9 +427,12 @@ int pthread_sigmask(
if ( !set )
set_errno_and_return_minus_one( EFAULT );
+ evaluate_signals = TRUE;
+
switch ( how ) {
case SIG_BLOCK:
api->signals_blocked |= *set;
+ evaluate_signals = FALSE;
break;
case SIG_UNBLOCK:
api->signals_blocked &= ~*set;
@@ -214,9 +444,20 @@ int pthread_sigmask(
set_errno_and_return_minus_one( EINVAL );
}
+ /* XXX are there critical section problems here? */
+
/* XXX evaluate the new set */
- return POSIX_NOT_IMPLEMENTED();
+ if ( evaluate_signals == TRUE ) {
+ if ( ~api->signals_blocked &
+ (api->signals_pending | _POSIX_signals_Pending) ) {
+ api->signals_global_pending &= _POSIX_signals_Pending;
+ _Thread_Executing->do_post_task_switch_extension = TRUE;
+ _Thread_Dispatch();
+ }
+ }
+
+ return 0;
}
/*
@@ -227,7 +468,16 @@ int sigpending(
sigset_t *set
)
{
- return POSIX_NOT_IMPLEMENTED();
+ POSIX_API_Control *api;
+
+ if ( !set )
+ set_errno_and_return_minus_one( EFAULT );
+
+ api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ *set = api->signals_pending | _POSIX_signals_Pending;
+
+ return 0;
}
/*
@@ -312,9 +562,13 @@ int kill(
* Only supported for the "calling process" (i.e. this node).
*/
- assert( pid == getpid() );
+ if( pid != getpid() );
+ set_errno_and_return_minus_one( ESRCH );
- /* SIGABRT comes from abort via assert */
+ if ( !sig || _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN )
+ return 0;
+
+ /* SIGABRT comes from abort via assert and must work no matter what */
if ( sig == SIGABRT ) {
exit( 1 );
}
@@ -330,18 +584,78 @@ int pthread_kill(
int sig
)
{
- return POSIX_NOT_IMPLEMENTED();
+ 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_handler == SIG_IGN )
+ return 0;
+
+ the_thread = _POSIX_Threads_Get( thread, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ case OBJECTS_REMOTE:
+ return ESRCH;
+ case OBJECTS_LOCAL:
+ /*
+ * If sig == 0 then just validate arguments
+ */
+
+ api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ if ( sig ) {
+
+ /* XXX critical section */
+
+ api->signals_pending |= signo_to_mask( sig );
+
+ if ( api->signals_pending & ~api->signals_blocked ) {
+ the_thread->do_post_task_switch_extension = TRUE;
+
+ /* XXX may have to unblock the task */
+
+ }
+ }
+ _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
)
{
- return POSIX_NOT_IMPLEMENTED();
+ 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/pthread.c b/cpukit/posix/src/pthread.c
index 484b93e847..aaf005312f 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -29,7 +29,7 @@ const pthread_attr_t _POSIX_Threads_Default_attributes = {
NULL, /* stackaddr */
STACK_MINIMUM_SIZE, /* stacksize */
PTHREAD_SCOPE_PROCESS, /* contentionscope */
- PTHREAD_INHERIT_SCHED, /* inheritsched */
+ PTHREAD_EXPLICIT_SCHED, /* inheritsched */
SCHED_FIFO, /* schedpolicy */
{ /* schedparam */
128, /* sched_priority */
@@ -123,6 +123,8 @@ boolean _POSIX_Threads_Create_extension(
api->schedparam.sched_priority =
_POSIX_Priority_From_core( created->current_priority );
+/* XXX set signal parameters -- block all signals for non-posix threads */
+
_Thread_queue_Initialize(
&api->Join_List,
OBJECTS_NO_CLASS, /* only used for proxy operations */