[7f72217e] | 1 | /* |
---|
[eb5a7e07] | 2 | * $Id$ |
---|
[5e9b32b] | 3 | */ |
---|
| 4 | |
---|
[f42b726] | 5 | #if HAVE_CONFIG_H |
---|
| 6 | #include "config.h" |
---|
| 7 | #endif |
---|
| 8 | |
---|
[e72d995a] | 9 | #include <assert.h> |
---|
| 10 | #include <errno.h> |
---|
[ea1a5bef] | 11 | #include <pthread.h> |
---|
[5e9b32b] | 12 | #include <signal.h> |
---|
| 13 | |
---|
[f4719d5a] | 14 | #include <rtems/system.h> |
---|
[fdec30b] | 15 | #include <rtems/score/isr.h> |
---|
[5e9b32b] | 16 | #include <rtems/score/thread.h> |
---|
[2291b71] | 17 | #include <rtems/score/tqdata.h> |
---|
[c53cfd0f] | 18 | #include <rtems/score/wkspace.h> |
---|
[188c82b] | 19 | #include <rtems/seterr.h> |
---|
[895efd9] | 20 | #include <rtems/posix/threadsup.h> |
---|
[20fff72] | 21 | #include <rtems/posix/psignal.h> |
---|
[fdec30b] | 22 | #include <rtems/posix/pthread.h> |
---|
[2291b71] | 23 | #include <rtems/posix/time.h> |
---|
[82f490f] | 24 | #include <stdio.h> |
---|
| 25 | |
---|
| 26 | |
---|
| 27 | /* |
---|
| 28 | * Currently 32 signals numbered 1-32 are defined |
---|
| 29 | */ |
---|
| 30 | |
---|
| 31 | #define SIGNAL_EMPTY_MASK 0x00000000 |
---|
| 32 | #define SIGNAL_ALL_MASK 0xffffffff |
---|
| 33 | |
---|
| 34 | #define signo_to_mask( _sig ) (1 << ((_sig) - 1)) |
---|
| 35 | |
---|
| 36 | #define is_valid_signo( _sig ) \ |
---|
| 37 | ((_sig) >= 1 && (_sig) <= 32 ) |
---|
[5e9b32b] | 38 | |
---|
[895efd9] | 39 | /*** PROCESS WIDE STUFF ****/ |
---|
| 40 | |
---|
[fdec30b] | 41 | sigset_t _POSIX_signals_Pending; |
---|
| 42 | |
---|
[da41ecbc] | 43 | void _POSIX_signals_Abnormal_termination_handler( int signo ) |
---|
[82f490f] | 44 | { |
---|
| 45 | exit( 1 ); |
---|
| 46 | } |
---|
[ea1a5bef] | 47 | |
---|
[82f490f] | 48 | #define SIG_ARRAY_MAX (SIGRTMAX + 1) |
---|
[fdec30b] | 49 | struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = { |
---|
| 50 | /* NO SIGNAL 0 */ SIGACTION_IGNORE, |
---|
[adae080a] | 51 | /* SIGHUP 1 */ SIGACTION_TERMINATE, |
---|
| 52 | /* SIGINT 2 */ SIGACTION_TERMINATE, |
---|
| 53 | /* SIGQUIT 3 */ SIGACTION_TERMINATE, |
---|
| 54 | /* SIGILL 4 */ SIGACTION_TERMINATE, |
---|
| 55 | /* SIGTRAP 5 */ SIGACTION_TERMINATE, |
---|
| 56 | /* SIGIOT 6 */ SIGACTION_TERMINATE, |
---|
| 57 | /* SIGABRT 6 SIGACTION_TERMINATE, -- alias for SIGIOT */ |
---|
| 58 | /* SIGEMT 7 */ SIGACTION_TERMINATE, |
---|
| 59 | /* SIGFPE 8 */ SIGACTION_TERMINATE, |
---|
| 60 | /* SIGKILL 9 */ SIGACTION_TERMINATE, |
---|
| 61 | /* SIGBUS 10 */ SIGACTION_TERMINATE, |
---|
| 62 | /* SIGSEGV 11 */ SIGACTION_TERMINATE, |
---|
| 63 | /* SIGSYS 12 */ SIGACTION_TERMINATE, |
---|
| 64 | /* SIGPIPE 13 */ SIGACTION_TERMINATE, |
---|
| 65 | /* SIGALRM 14 */ SIGACTION_TERMINATE, |
---|
| 66 | /* SIGTERM 15 */ SIGACTION_TERMINATE, |
---|
| 67 | /* SIGUSR1 16 */ SIGACTION_TERMINATE, |
---|
| 68 | /* SIGUSR2 17 */ SIGACTION_TERMINATE, |
---|
[df3e78a] | 69 | /* SIGRTMIN 18 */ SIGACTION_TERMINATE, |
---|
| 70 | /* SIGRT 19 */ SIGACTION_TERMINATE, |
---|
| 71 | /* SIGRT 20 */ SIGACTION_TERMINATE, |
---|
| 72 | /* SIGRT 21 */ SIGACTION_TERMINATE, |
---|
| 73 | /* SIGRT 22 */ SIGACTION_TERMINATE, |
---|
| 74 | /* SIGRT 23 */ SIGACTION_TERMINATE, |
---|
| 75 | /* SIGRT 24 */ SIGACTION_TERMINATE, |
---|
| 76 | /* SIGRT 25 */ SIGACTION_TERMINATE, |
---|
| 77 | /* SIGRT 26 */ SIGACTION_TERMINATE, |
---|
| 78 | /* SIGRT 27 */ SIGACTION_TERMINATE, |
---|
| 79 | /* SIGRT 28 */ SIGACTION_TERMINATE, |
---|
| 80 | /* SIGRT 29 */ SIGACTION_TERMINATE, |
---|
| 81 | /* SIGRT 30 */ SIGACTION_TERMINATE, |
---|
| 82 | /* SIGRT 31 */ SIGACTION_TERMINATE, |
---|
| 83 | /* SIGRTMAX 32 */ SIGACTION_TERMINATE |
---|
[fdec30b] | 84 | }; |
---|
| 85 | |
---|
[82f490f] | 86 | struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ]; |
---|
| 87 | |
---|
| 88 | Watchdog_Control _POSIX_signals_Alarm_timer; |
---|
| 89 | |
---|
| 90 | Thread_queue_Control _POSIX_signals_Wait_queue; |
---|
| 91 | |
---|
| 92 | Chain_Control _POSIX_signals_Inactive_siginfo; |
---|
| 93 | Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ]; |
---|
| 94 | |
---|
[fdec30b] | 95 | /*PAGE |
---|
| 96 | * |
---|
[82f490f] | 97 | * XXX - move these |
---|
[2291b71] | 98 | */ |
---|
| 99 | |
---|
[82f490f] | 100 | #define _States_Is_interruptible_signal( _states ) \ |
---|
| 101 | ( ((_states) & \ |
---|
| 102 | (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \ |
---|
| 103 | (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) |
---|
[2291b71] | 104 | |
---|
[82f490f] | 105 | /* |
---|
[ee979cd] | 106 | * _POSIX_signals_Post_switch_extension |
---|
[82f490f] | 107 | */ |
---|
[fdec30b] | 108 | |
---|
[98ed15e] | 109 | void _POSIX_signals_Post_switch_extension( |
---|
[fdec30b] | 110 | Thread_Control *the_thread |
---|
| 111 | ) |
---|
| 112 | { |
---|
| 113 | POSIX_API_Control *api; |
---|
| 114 | int signo; |
---|
[c8f5ab5] | 115 | ISR_Level level; |
---|
[fdec30b] | 116 | |
---|
| 117 | api = the_thread->API_Extensions[ THREAD_API_POSIX ]; |
---|
| 118 | |
---|
| 119 | /* |
---|
| 120 | * If we invoke any user code, there is the possibility that |
---|
[c8f5ab5] | 121 | * a new signal has been posted that we should process so we |
---|
| 122 | * restart the loop if a signal handler was invoked. |
---|
| 123 | * |
---|
| 124 | * The first thing done is to check there are any signals to be |
---|
| 125 | * processed at all. No point in doing this loop otherwise. |
---|
[fdec30b] | 126 | */ |
---|
| 127 | |
---|
| 128 | restart: |
---|
[c8f5ab5] | 129 | _ISR_Disable( level ); |
---|
| 130 | if ( !(~api->signals_blocked & |
---|
[b85649c4] | 131 | (api->signals_pending | _POSIX_signals_Pending)) ) { |
---|
| 132 | _ISR_Enable( level ); |
---|
| 133 | return; |
---|
| 134 | } |
---|
[9e28da4] | 135 | _ISR_Enable( level ); |
---|
[c8f5ab5] | 136 | |
---|
[fdec30b] | 137 | for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) { |
---|
| 138 | |
---|
| 139 | if ( _POSIX_signals_Check_signal( api, signo, FALSE ) ) |
---|
| 140 | goto restart; |
---|
| 141 | |
---|
| 142 | if ( _POSIX_signals_Check_signal( api, signo, TRUE ) ) |
---|
| 143 | goto restart; |
---|
| 144 | |
---|
| 145 | } |
---|
| 146 | |
---|
[781262bb] | 147 | /* XXX - add __SIGFIRSTNOTRT or something like that to newlib signal .h */ |
---|
[567ac45] | 148 | |
---|
| 149 | for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) { |
---|
[fdec30b] | 150 | |
---|
| 151 | if ( _POSIX_signals_Check_signal( api, signo, FALSE ) ) |
---|
| 152 | goto restart; |
---|
| 153 | |
---|
| 154 | if ( _POSIX_signals_Check_signal( api, signo, TRUE ) ) |
---|
| 155 | goto restart; |
---|
| 156 | |
---|
| 157 | } |
---|
| 158 | |
---|
| 159 | } |
---|
| 160 | |
---|
| 161 | /*PAGE |
---|
| 162 | * |
---|
| 163 | * _POSIX_signals_Alarm_TSR |
---|
| 164 | */ |
---|
| 165 | |
---|
| 166 | void _POSIX_signals_Alarm_TSR( |
---|
| 167 | Objects_Id id, |
---|
| 168 | void *argument |
---|
| 169 | ) |
---|
| 170 | { |
---|
[b85649c4] | 171 | int status; |
---|
| 172 | |
---|
| 173 | status = kill( getpid(), SIGALRM ); |
---|
| 174 | /* XXX can't print from an ISR, should this be fatal? */ |
---|
| 175 | assert( !status ); |
---|
[fdec30b] | 176 | } |
---|
[895efd9] | 177 | |
---|
| 178 | /*PAGE |
---|
[5e9b32b] | 179 | * |
---|
[895efd9] | 180 | * _POSIX_signals_Manager_Initialization |
---|
[5e9b32b] | 181 | */ |
---|
| 182 | |
---|
[c53cfd0f] | 183 | void _POSIX_signals_Manager_Initialization( |
---|
| 184 | int maximum_queued_signals |
---|
| 185 | ) |
---|
[5e9b32b] | 186 | { |
---|
[fdec30b] | 187 | unsigned32 signo; |
---|
| 188 | |
---|
| 189 | /* |
---|
| 190 | * Insure we have the same number of vectors and default vector entries |
---|
| 191 | */ |
---|
| 192 | |
---|
| 193 | assert( |
---|
| 194 | sizeof(_POSIX_signals_Vectors) == sizeof(_POSIX_signals_Default_vectors) |
---|
| 195 | ); |
---|
| 196 | |
---|
| 197 | memcpy( |
---|
| 198 | _POSIX_signals_Vectors, |
---|
| 199 | _POSIX_signals_Default_vectors, |
---|
| 200 | sizeof( _POSIX_signals_Vectors ) |
---|
| 201 | ); |
---|
| 202 | |
---|
| 203 | /* |
---|
| 204 | * Initialize the set of pending signals for the entire process |
---|
| 205 | */ |
---|
| 206 | |
---|
| 207 | sigemptyset( &_POSIX_signals_Pending ); |
---|
| 208 | |
---|
| 209 | /* |
---|
| 210 | * Initialize the timer used to implement alarm(). |
---|
| 211 | */ |
---|
| 212 | |
---|
| 213 | _Watchdog_Initialize( |
---|
| 214 | &_POSIX_signals_Alarm_timer, |
---|
| 215 | _POSIX_signals_Alarm_TSR, |
---|
| 216 | 0, |
---|
| 217 | NULL |
---|
| 218 | ); |
---|
| 219 | |
---|
[2291b71] | 220 | /* |
---|
| 221 | * Initialize the queue we use to block for signals |
---|
| 222 | */ |
---|
| 223 | |
---|
| 224 | _Thread_queue_Initialize( |
---|
| 225 | &_POSIX_signals_Wait_queue, |
---|
| 226 | OBJECTS_NO_CLASS, |
---|
| 227 | THREAD_QUEUE_DISCIPLINE_PRIORITY, |
---|
| 228 | STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL, |
---|
| 229 | NULL, |
---|
| 230 | EAGAIN |
---|
| 231 | ); |
---|
| 232 | |
---|
| 233 | /* XXX status codes */ |
---|
[c53cfd0f] | 234 | |
---|
[fdec30b] | 235 | /* |
---|
[c53cfd0f] | 236 | * Allocate the siginfo pools. |
---|
[fdec30b] | 237 | */ |
---|
| 238 | |
---|
| 239 | for ( signo=1 ; signo<= SIGRTMAX ; signo++ ) |
---|
| 240 | _Chain_Initialize_empty( &_POSIX_signals_Siginfo[ signo ] ); |
---|
| 241 | |
---|
[c53cfd0f] | 242 | _Chain_Initialize( |
---|
| 243 | &_POSIX_signals_Inactive_siginfo, |
---|
| 244 | _Workspace_Allocate_or_fatal_error( |
---|
| 245 | maximum_queued_signals * sizeof( POSIX_signals_Siginfo_node ) |
---|
| 246 | ), |
---|
| 247 | maximum_queued_signals, |
---|
| 248 | sizeof( POSIX_signals_Siginfo_node ) |
---|
| 249 | ); |
---|
[5e9b32b] | 250 | } |
---|