mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +00:00
first attempt at the routine which vectors signals.
This commit is contained in:
@@ -7,9 +7,11 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include <rtems/system.h>
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/isr.h>
|
||||||
#include <rtems/score/thread.h>
|
#include <rtems/score/thread.h>
|
||||||
#include <rtems/posix/seterr.h>
|
#include <rtems/posix/seterr.h>
|
||||||
#include <rtems/posix/threadsup.h>
|
#include <rtems/posix/threadsup.h>
|
||||||
|
#include <rtems/posix/pthread.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Currently 32 signals numbered 1-32 are defined
|
* Currently 32 signals numbered 1-32 are defined
|
||||||
@@ -21,14 +23,185 @@
|
|||||||
#define signo_to_mask( _sig ) (1 << ((_sig) - 1))
|
#define signo_to_mask( _sig ) (1 << ((_sig) - 1))
|
||||||
|
|
||||||
#define is_valid_signo( _sig ) \
|
#define is_valid_signo( _sig ) \
|
||||||
((signo_to_mask(_sig) & SIGNAL_ALL_MASK) != 0 )
|
((_sig) >= 1 && (_sig) <= 32 )
|
||||||
|
|
||||||
/*** PROCESS WIDE STUFF ****/
|
/*** PROCESS WIDE STUFF ****/
|
||||||
|
|
||||||
sigset_t _POSIX_signals_Blocked = SIGNAL_EMPTY_MASK;
|
sigset_t _POSIX_signals_Pending;
|
||||||
sigset_t _POSIX_signals_Pending = SIGNAL_EMPTY_MASK;
|
sigset_t _POSIX_signals_Ignored;
|
||||||
|
|
||||||
struct sigaction _POSIX_signals_Vectors[ SIGRTMAX ];
|
#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 ];
|
||||||
|
|
||||||
|
/*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
|
/*PAGE
|
||||||
*
|
*
|
||||||
@@ -37,7 +210,57 @@ struct sigaction _POSIX_signals_Vectors[ SIGRTMAX ];
|
|||||||
|
|
||||||
void _POSIX_signals_Manager_Initialization( void )
|
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 ];
|
*oact = _POSIX_signals_Vectors[ sig ];
|
||||||
|
|
||||||
/* XXX need to interpret some stuff here */
|
/* XXX need to interpret some stuff here */
|
||||||
|
/* XXX some signals cannot be ignored */
|
||||||
|
|
||||||
_POSIX_signals_Vectors[ sig ] = *act;
|
_POSIX_signals_Vectors[ sig ] = *act;
|
||||||
|
|
||||||
@@ -188,6 +412,9 @@ int pthread_sigmask(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
POSIX_API_Control *api;
|
POSIX_API_Control *api;
|
||||||
|
boolean evaluate_signals;
|
||||||
|
|
||||||
|
/* XXX some signals can not be ignored */
|
||||||
|
|
||||||
if ( !set && !oset )
|
if ( !set && !oset )
|
||||||
set_errno_and_return_minus_one( EFAULT );
|
set_errno_and_return_minus_one( EFAULT );
|
||||||
@@ -200,9 +427,12 @@ int pthread_sigmask(
|
|||||||
if ( !set )
|
if ( !set )
|
||||||
set_errno_and_return_minus_one( EFAULT );
|
set_errno_and_return_minus_one( EFAULT );
|
||||||
|
|
||||||
|
evaluate_signals = TRUE;
|
||||||
|
|
||||||
switch ( how ) {
|
switch ( how ) {
|
||||||
case SIG_BLOCK:
|
case SIG_BLOCK:
|
||||||
api->signals_blocked |= *set;
|
api->signals_blocked |= *set;
|
||||||
|
evaluate_signals = FALSE;
|
||||||
break;
|
break;
|
||||||
case SIG_UNBLOCK:
|
case SIG_UNBLOCK:
|
||||||
api->signals_blocked &= ~*set;
|
api->signals_blocked &= ~*set;
|
||||||
@@ -214,9 +444,20 @@ int pthread_sigmask(
|
|||||||
set_errno_and_return_minus_one( EINVAL );
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX are there critical section problems here? */
|
||||||
|
|
||||||
/* XXX evaluate the new set */
|
/* 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
|
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).
|
* 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 ) {
|
if ( sig == SIGABRT ) {
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
}
|
}
|
||||||
@@ -330,18 +584,78 @@ int pthread_kill(
|
|||||||
int sig
|
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
|
* 3.4.1 Schedule Alarm, P1003.1b-1993, p. 79
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Watchdog_Control _POSIX_signals_Alarm_timer;
|
||||||
|
|
||||||
unsigned int alarm(
|
unsigned int alarm(
|
||||||
unsigned int seconds
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ const pthread_attr_t _POSIX_Threads_Default_attributes = {
|
|||||||
NULL, /* stackaddr */
|
NULL, /* stackaddr */
|
||||||
STACK_MINIMUM_SIZE, /* stacksize */
|
STACK_MINIMUM_SIZE, /* stacksize */
|
||||||
PTHREAD_SCOPE_PROCESS, /* contentionscope */
|
PTHREAD_SCOPE_PROCESS, /* contentionscope */
|
||||||
PTHREAD_INHERIT_SCHED, /* inheritsched */
|
PTHREAD_EXPLICIT_SCHED, /* inheritsched */
|
||||||
SCHED_FIFO, /* schedpolicy */
|
SCHED_FIFO, /* schedpolicy */
|
||||||
{ /* schedparam */
|
{ /* schedparam */
|
||||||
128, /* sched_priority */
|
128, /* sched_priority */
|
||||||
@@ -123,6 +123,8 @@ boolean _POSIX_Threads_Create_extension(
|
|||||||
api->schedparam.sched_priority =
|
api->schedparam.sched_priority =
|
||||||
_POSIX_Priority_From_core( created->current_priority );
|
_POSIX_Priority_From_core( created->current_priority );
|
||||||
|
|
||||||
|
/* XXX set signal parameters -- block all signals for non-posix threads */
|
||||||
|
|
||||||
_Thread_queue_Initialize(
|
_Thread_queue_Initialize(
|
||||||
&api->Join_List,
|
&api->Join_List,
|
||||||
OBJECTS_NO_CLASS, /* only used for proxy operations */
|
OBJECTS_NO_CLASS, /* only used for proxy operations */
|
||||||
|
|||||||
@@ -7,9 +7,11 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include <rtems/system.h>
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/isr.h>
|
||||||
#include <rtems/score/thread.h>
|
#include <rtems/score/thread.h>
|
||||||
#include <rtems/posix/seterr.h>
|
#include <rtems/posix/seterr.h>
|
||||||
#include <rtems/posix/threadsup.h>
|
#include <rtems/posix/threadsup.h>
|
||||||
|
#include <rtems/posix/pthread.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Currently 32 signals numbered 1-32 are defined
|
* Currently 32 signals numbered 1-32 are defined
|
||||||
@@ -21,14 +23,185 @@
|
|||||||
#define signo_to_mask( _sig ) (1 << ((_sig) - 1))
|
#define signo_to_mask( _sig ) (1 << ((_sig) - 1))
|
||||||
|
|
||||||
#define is_valid_signo( _sig ) \
|
#define is_valid_signo( _sig ) \
|
||||||
((signo_to_mask(_sig) & SIGNAL_ALL_MASK) != 0 )
|
((_sig) >= 1 && (_sig) <= 32 )
|
||||||
|
|
||||||
/*** PROCESS WIDE STUFF ****/
|
/*** PROCESS WIDE STUFF ****/
|
||||||
|
|
||||||
sigset_t _POSIX_signals_Blocked = SIGNAL_EMPTY_MASK;
|
sigset_t _POSIX_signals_Pending;
|
||||||
sigset_t _POSIX_signals_Pending = SIGNAL_EMPTY_MASK;
|
sigset_t _POSIX_signals_Ignored;
|
||||||
|
|
||||||
struct sigaction _POSIX_signals_Vectors[ SIGRTMAX ];
|
#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 ];
|
||||||
|
|
||||||
|
/*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
|
/*PAGE
|
||||||
*
|
*
|
||||||
@@ -37,7 +210,57 @@ struct sigaction _POSIX_signals_Vectors[ SIGRTMAX ];
|
|||||||
|
|
||||||
void _POSIX_signals_Manager_Initialization( void )
|
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 ];
|
*oact = _POSIX_signals_Vectors[ sig ];
|
||||||
|
|
||||||
/* XXX need to interpret some stuff here */
|
/* XXX need to interpret some stuff here */
|
||||||
|
/* XXX some signals cannot be ignored */
|
||||||
|
|
||||||
_POSIX_signals_Vectors[ sig ] = *act;
|
_POSIX_signals_Vectors[ sig ] = *act;
|
||||||
|
|
||||||
@@ -188,6 +412,9 @@ int pthread_sigmask(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
POSIX_API_Control *api;
|
POSIX_API_Control *api;
|
||||||
|
boolean evaluate_signals;
|
||||||
|
|
||||||
|
/* XXX some signals can not be ignored */
|
||||||
|
|
||||||
if ( !set && !oset )
|
if ( !set && !oset )
|
||||||
set_errno_and_return_minus_one( EFAULT );
|
set_errno_and_return_minus_one( EFAULT );
|
||||||
@@ -200,9 +427,12 @@ int pthread_sigmask(
|
|||||||
if ( !set )
|
if ( !set )
|
||||||
set_errno_and_return_minus_one( EFAULT );
|
set_errno_and_return_minus_one( EFAULT );
|
||||||
|
|
||||||
|
evaluate_signals = TRUE;
|
||||||
|
|
||||||
switch ( how ) {
|
switch ( how ) {
|
||||||
case SIG_BLOCK:
|
case SIG_BLOCK:
|
||||||
api->signals_blocked |= *set;
|
api->signals_blocked |= *set;
|
||||||
|
evaluate_signals = FALSE;
|
||||||
break;
|
break;
|
||||||
case SIG_UNBLOCK:
|
case SIG_UNBLOCK:
|
||||||
api->signals_blocked &= ~*set;
|
api->signals_blocked &= ~*set;
|
||||||
@@ -214,9 +444,20 @@ int pthread_sigmask(
|
|||||||
set_errno_and_return_minus_one( EINVAL );
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX are there critical section problems here? */
|
||||||
|
|
||||||
/* XXX evaluate the new set */
|
/* 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
|
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).
|
* 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 ) {
|
if ( sig == SIGABRT ) {
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
}
|
}
|
||||||
@@ -330,18 +584,78 @@ int pthread_kill(
|
|||||||
int sig
|
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
|
* 3.4.1 Schedule Alarm, P1003.1b-1993, p. 79
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Watchdog_Control _POSIX_signals_Alarm_timer;
|
||||||
|
|
||||||
unsigned int alarm(
|
unsigned int alarm(
|
||||||
unsigned int seconds
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ const pthread_attr_t _POSIX_Threads_Default_attributes = {
|
|||||||
NULL, /* stackaddr */
|
NULL, /* stackaddr */
|
||||||
STACK_MINIMUM_SIZE, /* stacksize */
|
STACK_MINIMUM_SIZE, /* stacksize */
|
||||||
PTHREAD_SCOPE_PROCESS, /* contentionscope */
|
PTHREAD_SCOPE_PROCESS, /* contentionscope */
|
||||||
PTHREAD_INHERIT_SCHED, /* inheritsched */
|
PTHREAD_EXPLICIT_SCHED, /* inheritsched */
|
||||||
SCHED_FIFO, /* schedpolicy */
|
SCHED_FIFO, /* schedpolicy */
|
||||||
{ /* schedparam */
|
{ /* schedparam */
|
||||||
128, /* sched_priority */
|
128, /* sched_priority */
|
||||||
@@ -123,6 +123,8 @@ boolean _POSIX_Threads_Create_extension(
|
|||||||
api->schedparam.sched_priority =
|
api->schedparam.sched_priority =
|
||||||
_POSIX_Priority_From_core( created->current_priority );
|
_POSIX_Priority_From_core( created->current_priority );
|
||||||
|
|
||||||
|
/* XXX set signal parameters -- block all signals for non-posix threads */
|
||||||
|
|
||||||
_Thread_queue_Initialize(
|
_Thread_queue_Initialize(
|
||||||
&api->Join_List,
|
&api->Join_List,
|
||||||
OBJECTS_NO_CLASS, /* only used for proxy operations */
|
OBJECTS_NO_CLASS, /* only used for proxy operations */
|
||||||
|
|||||||
Reference in New Issue
Block a user