summaryrefslogtreecommitdiffstats
path: root/cpukit/posix
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2010-07-27 16:34:26 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2010-07-27 16:34:26 +0000
commit1102485cbbcb24b77d7e0e178ba8fbe51d919470 (patch)
tree17e78ba02bc40f3e6810bcbab5db9eb113a8c8ad /cpukit/posix
parent2010-07-27 Gedare Bloom <giddyup44@yahoo.com> (diff)
downloadrtems-1102485cbbcb24b77d7e0e178ba8fbe51d919470.tar.bz2
2010-07-27 Vinu Rajashekhar <vinutheraj@gmail.com>
PR 1630/cpukit * posix/src/psignalchecksignal.c, posix/src/sigtimedwait.c: sigtimedwait() was not completely following the POSIX specification.
Diffstat (limited to 'cpukit/posix')
-rw-r--r--cpukit/posix/src/psignalchecksignal.c16
-rw-r--r--cpukit/posix/src/sigtimedwait.c19
2 files changed, 31 insertions, 4 deletions
diff --git a/cpukit/posix/src/psignalchecksignal.c b/cpukit/posix/src/psignalchecksignal.c
index 1ed3bacdf7..8bba7a4226 100644
--- a/cpukit/posix/src/psignalchecksignal.c
+++ b/cpukit/posix/src/psignalchecksignal.c
@@ -19,6 +19,7 @@
#include <errno.h>
#include <pthread.h>
#include <signal.h>
+#include <string.h>
#include <rtems/system.h>
#include <rtems/score/isr.h>
@@ -46,6 +47,7 @@ bool _POSIX_signals_Check_signal(
{
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 ) )
@@ -73,6 +75,14 @@ bool _POSIX_signals_Check_signal(
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 ) {
@@ -89,6 +99,12 @@ bool _POSIX_signals_Check_signal(
}
/*
+ * 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;
diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c
index 70b632b6de..41ebf88677 100644
--- a/cpukit/posix/src/sigtimedwait.c
+++ b/cpukit/posix/src/sigtimedwait.c
@@ -26,7 +26,7 @@
#include <rtems/posix/time.h>
#include <rtems/score/isr.h>
-int _POSIX_signals_Get_highest(
+int _POSIX_signals_Get_lowest(
sigset_t set
)
{
@@ -115,7 +115,7 @@ int sigtimedwait(
_ISR_Disable( level );
if ( *set & api->signals_pending ) {
/* XXX real info later */
- the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending );
+ the_info->si_signo = _POSIX_signals_Get_lowest( api->signals_pending );
_POSIX_signals_Clear_signals(
api,
the_info->si_signo,
@@ -133,7 +133,7 @@ int sigtimedwait(
/* Process pending signals? */
if ( *set & _POSIX_signals_Pending ) {
- signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending );
+ signo = _POSIX_signals_Get_lowest( _POSIX_signals_Pending );
_POSIX_signals_Clear_signals( api, signo, the_info, true, false );
_ISR_Enable( level );
@@ -161,6 +161,17 @@ int sigtimedwait(
*/
_POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, false, false );
- errno = _Thread_Executing->Wait.return_code;
+
+ /* Set errno only if return code is not EINTR or
+ * if EINTR was caused by a signal being caught, which
+ * was not in our set.
+ */
+
+ if ( (_Thread_Executing->Wait.return_code != EINTR)
+ || !(*set & signo_to_mask( the_info->si_signo )) ) {
+ errno = _Thread_Executing->Wait.return_code;
+ return -1;
+ }
+
return the_info->si_signo;
}