mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-25 22:07:15 +00:00
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.
This commit is contained in:
@@ -5,11 +5,67 @@
|
||||
#ifndef __RTEMS_POSIX_SIGNALS_h
|
||||
#define __RTEMS_POSIX_SIGNALS_h
|
||||
|
||||
#include <rtems/posix/pthread.h>
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
@@ -29,8 +29,16 @@ PTHREAD_PIECES=\
|
||||
pthreadattrgetinheritsched pthreadattrsetinheritsched \
|
||||
pthreadattrgetscope pthreadattrsetscope
|
||||
|
||||
C_PIECES= adasupp cond getpid key mutex $(PTHREAD_PIECES) psignal sched time \
|
||||
PSIGNAL_PIECES=\
|
||||
psignal alarm kill killinfo pause pthreadkill pthreadsigmask \
|
||||
sigaction sigaddset sigdelset sigemptyset sigfillset sigismember \
|
||||
sigpending sigprocmask sigqueue sigsuspend sigtimedwait sigwait \
|
||||
sigwaitinfo
|
||||
|
||||
C_PIECES= adasupp cond getpid key mutex $(PTHREAD_PIECES) \
|
||||
$(PSIGNAL_PIECES) sched time \
|
||||
types unistd $(ENOSYS_C_PIECES)
|
||||
|
||||
C_FILES=$(C_PIECES:%=%.c)
|
||||
C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
|
||||
|
||||
|
||||
48
c/src/exec/posix/src/alarm.c
Normal file
48
c/src/exec/posix/src/alarm.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
50
c/src/exec/posix/src/kill.c
Normal file
50
c/src/exec/posix/src/kill.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
|
||||
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 <reent.h>
|
||||
|
||||
int _kill_r(
|
||||
struct _reent *ptr,
|
||||
pid_t pid,
|
||||
int sig
|
||||
)
|
||||
{
|
||||
return kill( pid, sig );
|
||||
}
|
||||
#endif
|
||||
|
||||
328
c/src/exec/posix/src/killinfo.c
Normal file
328
c/src/exec/posix/src/killinfo.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
#include <rtems/score/isr.h>
|
||||
|
||||
/*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;
|
||||
}
|
||||
39
c/src/exec/posix/src/pause.c
Normal file
39
c/src/exec/posix/src/pause.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
@@ -18,40 +18,19 @@
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/time.h>
|
||||
|
||||
/*
|
||||
* 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 <reent.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
79
c/src/exec/posix/src/pthreadkill.c
Normal file
79
c/src/exec/posix/src/pthreadkill.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
|
||||
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();
|
||||
}
|
||||
71
c/src/exec/posix/src/pthreadsigmask.c
Normal file
71
c/src/exec/posix/src/pthreadsigmask.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
|
||||
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;
|
||||
}
|
||||
85
c/src/exec/posix/src/sigaction.c
Normal file
85
c/src/exec/posix/src/sigaction.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
#include <rtems/score/isr.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
40
c/src/exec/posix/src/sigaddset.c
Normal file
40
c/src/exec/posix/src/sigaddset.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
|
||||
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;
|
||||
}
|
||||
45
c/src/exec/posix/src/sigdelset.c
Normal file
45
c/src/exec/posix/src/sigdelset.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
34
c/src/exec/posix/src/sigemptyset.c
Normal file
34
c/src/exec/posix/src/sigemptyset.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
|
||||
int sigemptyset(
|
||||
sigset_t *set
|
||||
)
|
||||
{
|
||||
if ( !set )
|
||||
set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
*set = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
34
c/src/exec/posix/src/sigfillset.c
Normal file
34
c/src/exec/posix/src/sigfillset.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
|
||||
int sigfillset(
|
||||
sigset_t *set
|
||||
)
|
||||
{
|
||||
if ( !set )
|
||||
set_errno_and_return_minus_one( EINVAL );
|
||||
|
||||
*set = SIGNAL_ALL_MASK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
43
c/src/exec/posix/src/sigismember.c
Normal file
43
c/src/exec/posix/src/sigismember.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
38
c/src/exec/posix/src/sigpending.c
Normal file
38
c/src/exec/posix/src/sigpending.c
Normal file
@@ -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 <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
|
||||
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;
|
||||
}
|
||||
37
c/src/exec/posix/src/sigprocmask.c
Normal file
37
c/src/exec/posix/src/sigprocmask.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
|
||||
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 );
|
||||
}
|
||||
31
c/src/exec/posix/src/sigqueue.c
Normal file
31
c/src/exec/posix/src/sigqueue.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
|
||||
int sigqueue(
|
||||
pid_t pid,
|
||||
int signo,
|
||||
const union sigval value
|
||||
)
|
||||
{
|
||||
return killinfo( pid, signo, &value );
|
||||
}
|
||||
|
||||
43
c/src/exec/posix/src/sigsuspend.c
Normal file
43
c/src/exec/posix/src/sigsuspend.c
Normal file
@@ -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 <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
|
||||
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;
|
||||
}
|
||||
117
c/src/exec/posix/src/sigtimedwait.c
Normal file
117
c/src/exec/posix/src/sigtimedwait.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
#include <rtems/posix/seterr.h>
|
||||
#include <rtems/posix/time.h>
|
||||
|
||||
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;
|
||||
}
|
||||
43
c/src/exec/posix/src/sigwait.c
Normal file
43
c/src/exec/posix/src/sigwait.c
Normal file
@@ -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 <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
31
c/src/exec/posix/src/sigwaitinfo.c
Normal file
31
c/src/exec/posix/src/sigwaitinfo.c
Normal file
@@ -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 <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
#include <rtems/posix/psignal.h>
|
||||
|
||||
int sigwaitinfo(
|
||||
const sigset_t *set,
|
||||
siginfo_t *info
|
||||
)
|
||||
{
|
||||
return sigtimedwait( set, info, NULL );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user