summaryrefslogtreecommitdiffstats
path: root/cpukit/posix/src/psignalchecksignal.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/posix/src/psignalchecksignal.c')
-rw-r--r--cpukit/posix/src/psignalchecksignal.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/cpukit/posix/src/psignalchecksignal.c b/cpukit/posix/src/psignalchecksignal.c
new file mode 100644
index 0000000000..8bba7a4226
--- /dev/null
+++ b/cpukit/posix/src/psignalchecksignal.c
@@ -0,0 +1,113 @@
+/*
+ * COPYRIGHT (c) 1989-2007.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(RTEMS_DEBUG)
+ #include <assert.h>
+#endif
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tqdata.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/seterr.h>
+#include <rtems/posix/threadsup.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/time.h>
+#include <stdio.h>
+
+
+/*PAGE
+ *
+ * _POSIX_signals_Check_signal
+ */
+
+bool _POSIX_signals_Check_signal(
+ POSIX_API_Control *api,
+ int signo,
+ bool is_global
+)
+{
+ siginfo_t siginfo_struct;
+ sigset_t saved_signals_blocked;
+ Thread_Wait_information stored_thread_wait_information;
+
+ if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct,
+ is_global, true ) )
+ return false;
+
+ /*
+ * Since we made a union of these, only one test is necessary but this is
+ * safer.
+ */
+ #if defined(RTEMS_DEBUG)
+ assert( _POSIX_signals_Vectors[ signo ].sa_handler ||
+ _POSIX_signals_Vectors[ signo ].sa_sigaction );
+ #endif
+
+ /*
+ * Just to prevent sending a signal which is currently being ignored.
+ */
+ if ( _POSIX_signals_Vectors[ signo ].sa_handler == SIG_IGN )
+ return false;
+
+ /*
+ * Block the signals requested in sa_mask
+ */
+ saved_signals_blocked = api->signals_blocked;
+ api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask;
+
+ /*
+ * We have to save the blocking information of the current wait queue
+ * because the signal handler may subsequently go on and put the thread
+ * on a wait queue, for its own purposes.
+ */
+ memcpy( &stored_thread_wait_information, &_Thread_Executing->Wait,
+ sizeof( Thread_Wait_information ));
+
+ /*
+ * Here, the signal handler function executes
+ */
+ switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) {
+ case SA_SIGINFO:
+ (*_POSIX_signals_Vectors[ signo ].sa_sigaction)(
+ signo,
+ &siginfo_struct,
+ NULL /* context is undefined per 1003.1b-1993, p. 66 */
+ );
+ break;
+ default:
+ (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo );
+ break;
+ }
+
+ /*
+ * Restore the blocking information
+ */
+ memcpy( &_Thread_Executing->Wait, &stored_thread_wait_information,
+ sizeof( Thread_Wait_information ));
+
+ /*
+ * Restore the previous set of blocked signals
+ */
+ api->signals_blocked = saved_signals_blocked;
+
+ return true;
+}