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.
This commit is contained in:
Joel Sherrill
2010-07-27 16:34:26 +00:00
parent 019fd4b680
commit 1102485cbb
3 changed files with 37 additions and 4 deletions

View File

@@ -1,3 +1,9 @@
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.
2010-07-26 Joel Sherrill <joel.sherrilL@OARcorp.com> 2010-07-26 Joel Sherrill <joel.sherrilL@OARcorp.com>
* score/src/threadget.c: Conditionalize a check that can only occur * score/src/threadget.c: Conditionalize a check that can only occur

View File

@@ -19,6 +19,7 @@
#include <errno.h> #include <errno.h>
#include <pthread.h> #include <pthread.h>
#include <signal.h> #include <signal.h>
#include <string.h>
#include <rtems/system.h> #include <rtems/system.h>
#include <rtems/score/isr.h> #include <rtems/score/isr.h>
@@ -46,6 +47,7 @@ bool _POSIX_signals_Check_signal(
{ {
siginfo_t siginfo_struct; siginfo_t siginfo_struct;
sigset_t saved_signals_blocked; sigset_t saved_signals_blocked;
Thread_Wait_information stored_thread_wait_information;
if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct, if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct,
is_global, true ) ) is_global, true ) )
@@ -72,6 +74,14 @@ bool _POSIX_signals_Check_signal(
saved_signals_blocked = api->signals_blocked; saved_signals_blocked = api->signals_blocked;
api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask; 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 * Here, the signal handler function executes
*/ */
@@ -88,6 +98,12 @@ bool _POSIX_signals_Check_signal(
break; break;
} }
/*
* Restore the blocking information
*/
memcpy( &_Thread_Executing->Wait, &stored_thread_wait_information,
sizeof( Thread_Wait_information ));
/* /*
* Restore the previous set of blocked signals * Restore the previous set of blocked signals
*/ */

View File

@@ -26,7 +26,7 @@
#include <rtems/posix/time.h> #include <rtems/posix/time.h>
#include <rtems/score/isr.h> #include <rtems/score/isr.h>
int _POSIX_signals_Get_highest( int _POSIX_signals_Get_lowest(
sigset_t set sigset_t set
) )
{ {
@@ -115,7 +115,7 @@ int sigtimedwait(
_ISR_Disable( level ); _ISR_Disable( level );
if ( *set & api->signals_pending ) { if ( *set & api->signals_pending ) {
/* XXX real info later */ /* 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( _POSIX_signals_Clear_signals(
api, api,
the_info->si_signo, the_info->si_signo,
@@ -133,7 +133,7 @@ int sigtimedwait(
/* Process pending signals? */ /* Process pending signals? */
if ( *set & _POSIX_signals_Pending ) { 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 ); _POSIX_signals_Clear_signals( api, signo, the_info, true, false );
_ISR_Enable( level ); _ISR_Enable( level );
@@ -161,6 +161,17 @@ int sigtimedwait(
*/ */
_POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, false, false ); _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; return the_info->si_signo;
} }