File indexing completed on 2025-05-11 08:24:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifdef HAVE_CONFIG_H
0037 #include "config.h"
0038 #endif
0039
0040 #include <signal.h>
0041
0042 #include <rtems/posix/pthreadimpl.h>
0043 #include <rtems/posix/psignalimpl.h>
0044 #include <rtems/posix/posixapi.h>
0045 #include <rtems/score/threadqimpl.h>
0046 #include <rtems/score/todimpl.h>
0047 #include <rtems/score/watchdogimpl.h>
0048 #include <rtems/score/isr.h>
0049
0050 static int _POSIX_signals_Get_lowest(
0051 sigset_t set
0052 )
0053 {
0054 int signo;
0055
0056 for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
0057 if ( set & signo_to_mask( signo ) ) {
0058 goto found_it;
0059 }
0060 }
0061
0062
0063
0064
0065
0066 #if (SIGHUP != 1)
0067 #error "Assumption that SIGHUP==1 violated!!"
0068 #endif
0069 for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) {
0070 if ( set & signo_to_mask( signo ) ) {
0071 goto found_it;
0072 }
0073 }
0074
0075
0076
0077
0078
0079
0080 found_it:
0081 return signo;
0082 }
0083
0084
0085
0086
0087 int sigtimedwait(
0088 const sigset_t *__restrict set,
0089 siginfo_t *__restrict info,
0090 const struct timespec *__restrict timeout
0091 )
0092 {
0093 Thread_Control *executing;
0094 POSIX_API_Control *api;
0095 siginfo_t signal_information;
0096 siginfo_t *the_info;
0097 int signo;
0098 Thread_queue_Context queue_context;
0099 int error;
0100
0101
0102
0103
0104 if ( !set )
0105 rtems_set_errno_and_return_minus_one( EINVAL );
0106
0107 _Thread_queue_Context_initialize( &queue_context );
0108
0109
0110
0111
0112
0113 if ( timeout != NULL ) {
0114 _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
0115 &queue_context,
0116 timeout,
0117 false
0118 );
0119 } else {
0120 _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
0121 }
0122
0123
0124
0125
0126
0127 the_info = ( info ) ? info : &signal_information;
0128
0129 executing = _Thread_Get_executing();
0130 api = executing->API_Extensions[ THREAD_API_POSIX ];
0131
0132
0133
0134
0135
0136
0137
0138 _POSIX_signals_Acquire( &queue_context );
0139 if ( *set & api->signals_pending ) {
0140
0141 the_info->si_signo = _POSIX_signals_Get_lowest( api->signals_pending );
0142 _POSIX_signals_Clear_signals(
0143 api,
0144 the_info->si_signo,
0145 the_info,
0146 false,
0147 false,
0148 false
0149 );
0150 _POSIX_signals_Release( &queue_context );
0151
0152 the_info->si_code = SI_USER;
0153 the_info->si_value.sival_int = 0;
0154 return the_info->si_signo;
0155 }
0156
0157
0158
0159 if ( *set & _POSIX_signals_Pending ) {
0160 signo = _POSIX_signals_Get_lowest( _POSIX_signals_Pending );
0161 _POSIX_signals_Clear_signals( api, signo, the_info, true, false, false );
0162 _POSIX_signals_Release( &queue_context );
0163
0164 the_info->si_signo = signo;
0165 the_info->si_code = SI_USER;
0166 the_info->si_value.sival_int = 0;
0167 return signo;
0168 }
0169
0170 the_info->si_signo = -1;
0171
0172 executing->Wait.option = *set;
0173 executing->Wait.return_argument = the_info;
0174 _Thread_queue_Context_set_thread_state(
0175 &queue_context,
0176 STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL
0177 );
0178 _Thread_queue_Enqueue(
0179 &_POSIX_signals_Wait_queue.Queue,
0180 POSIX_SIGNALS_TQ_OPERATIONS,
0181 executing,
0182 &queue_context
0183 );
0184
0185
0186
0187
0188
0189
0190 _POSIX_signals_Clear_signals(
0191 api,
0192 the_info->si_signo,
0193 the_info,
0194 false,
0195 false,
0196 true
0197 );
0198
0199
0200
0201
0202
0203
0204 error = _POSIX_Get_error_after_wait( executing );
0205
0206 if (
0207 error != EINTR
0208 || ( *set & signo_to_mask( the_info->si_signo ) ) == 0
0209 ) {
0210 if ( error == ETIMEDOUT ) {
0211 error = EAGAIN;
0212 }
0213
0214 rtems_set_errno_and_return_minus_one( error );
0215 }
0216
0217 return the_info->si_signo;
0218 }