31
31
#include "w32fd.h"
32
32
#include <errno.h>
33
33
#include <signal.h>
34
- #include "inc\defs .h"
34
+ #include "signal_internal .h"
35
35
36
36
/* pending signals to be processed */
37
37
sigset_t pending_signals ;
@@ -96,261 +96,7 @@ sw_init_signal_handler_table() {
96
96
memset (sig_handlers , 0 , sizeof (sig_handlers ));
97
97
}
98
98
99
- /* child processes */
100
- #define MAX_CHILDREN 50
101
- struct _children {
102
- HANDLE handles [MAX_CHILDREN ];
103
- DWORD process_id [MAX_CHILDREN ];
104
- /* total children */
105
- DWORD num_children ;
106
- /* #zombies */
107
- /* (num_chileren - zombies) are live children */
108
- DWORD num_zombies ;
109
- } children ;
110
-
111
- int
112
- sw_add_child (HANDLE child , DWORD pid ) {
113
- DWORD first_zombie_index ;
114
-
115
- debug ("Register child %p pid %d, %d zombies of %d" , child , pid ,
116
- children .num_zombies , children .num_children );
117
- if (children .num_children == MAX_CHILDREN ) {
118
- errno = ENOMEM ;
119
- return -1 ;
120
- }
121
- if (children .num_zombies ) {
122
- first_zombie_index = children .num_children - children .num_zombies ;
123
- children .handles [children .num_children ] = children .handles [first_zombie_index ];
124
- children .process_id [children .num_children ] = children .handles [first_zombie_index ];
125
-
126
- children .handles [first_zombie_index ] = child ;
127
- children .process_id [first_zombie_index ] = pid ;
128
- }
129
- else {
130
- children .handles [children .num_children ] = child ;
131
- children .process_id [children .num_children ] = pid ;
132
- }
133
-
134
-
135
- children .num_children ++ ;
136
- return 0 ;
137
- }
138
-
139
- int
140
- sw_remove_child_at_index (DWORD index ) {
141
- DWORD last_non_zombie ;
142
-
143
- debug ("Unregister child at index %d, %d zombies of %d" , index ,
144
- children .num_zombies , children .num_children );
145
-
146
- if ((index >= children .num_children )
147
- || (children .num_children == 0 ) ){
148
- errno = EINVAL ;
149
- return -1 ;
150
- }
151
-
152
- CloseHandle (children .handles [index ]);
153
- if (children .num_zombies == 0 ) {
154
- children .handles [index ] = children .handles [children .num_children - 1 ];
155
- children .process_id [index ] = children .process_id [children .num_children - 1 ];
156
- }
157
- else {
158
- /* if its a zombie */
159
- if (index >= (children .num_children - children .num_zombies )) {
160
- children .handles [index ] = children .handles [children .num_children - 1 ];
161
- children .process_id [index ] = children .handles [children .num_children - 1 ];
162
- children .num_zombies -- ;
163
- }
164
- else {
165
- last_non_zombie = children .num_children - children .num_zombies - 1 ;
166
- children .handles [index ] = children .handles [last_non_zombie ];
167
- children .process_id [index ] = children .process_id [last_non_zombie ];
168
-
169
- children .handles [last_non_zombie ] = children .handles [children .num_children - 1 ];
170
- children .process_id [last_non_zombie ] = children .handles [children .num_children - 1 ];
171
- }
172
- }
173
-
174
- children .num_children -- ;
175
- return 0 ;
176
- }
177
-
178
- int
179
- sw_child_to_zombie (DWORD index ) {
180
- DWORD last_non_zombie ;
181
-
182
- debug ("zombie'ing child at index %d, %d zombies of %d" , index ,
183
- children .num_zombies , children .num_children );
184
-
185
- if (index >= children .num_children ) {
186
- errno = EINVAL ;
187
- return -1 ;
188
- }
189
-
190
- /* TODO - turn child to zombie*/
191
- return 0 ;
192
- }
193
-
194
- int
195
- sw_remove_child (HANDLE child ) {
196
- HANDLE * handles = children .handles ;
197
- DWORD num_children = children .num_children ;
198
-
199
- while (num_children ) {
200
- if (* handles == child )
201
- return sw_remove_child_at_index (children .num_children - num_children );
202
- handles ++ ;
203
- num_children -- ;
204
- }
205
-
206
- errno = EINVAL ;
207
- return -1 ;
208
- }
209
-
210
- int waitpid (int pid , int * status , int options ) {
211
- DWORD index , ret , ret_id , exit_code , timeout = 0 ;
212
- HANDLE process = NULL ;
213
-
214
- if (options & (~WNOHANG )) {
215
- errno = ENOTSUP ;
216
- DebugBreak ();
217
- return -1 ;
218
- }
219
-
220
- if ((pid < -1 ) || (pid == 0 )) {
221
- errno = ENOTSUP ;
222
- DebugBreak ();
223
- return -1 ;
224
- }
225
-
226
- if (children .num_children == 0 ) {
227
- errno = ECHILD ;
228
- return -1 ;
229
- }
230
-
231
- if (pid > 0 ) {
232
- if (options != 0 ) {
233
- errno = ENOTSUP ;
234
- DebugBreak ();
235
- return -1 ;
236
- }
237
- /* find entry in table */
238
- for (index = 0 ; index < children .num_children ; index ++ )
239
- if (children .process_id [index ] == pid )
240
- break ;
241
-
242
- if (index == children .num_children ) {
243
- errno = ECHILD ;
244
- return -1 ;
245
- }
246
-
247
- process = children .handles [index ];
248
- ret = WaitForSingleObject (process , INFINITE );
249
- if (ret != WAIT_OBJECT_0 )
250
- DebugBreak ();//fatal
251
-
252
- ret_id = children .process_id [index ];
253
- GetExitCodeProcess (process , & exit_code );
254
- CloseHandle (process );
255
- sw_remove_child_at_index (index );
256
- if (status )
257
- * status = exit_code ;
258
- return ret_id ;
259
- }
260
-
261
- /* pid = -1*/
262
- timeout = INFINITE ;
263
- if (options & WNOHANG )
264
- timeout = 0 ;
265
- ret = WaitForMultipleObjects (children .num_children , children .handles , FALSE, timeout );
266
- if ((ret >= WAIT_OBJECT_0 ) && (ret < (WAIT_OBJECT_0 + children .num_children ))) {
267
- index = ret - WAIT_OBJECT_0 ;
268
- process = children .handles [index ];
269
- ret_id = children .process_id [index ];
270
- GetExitCodeProcess (process , & exit_code );
271
- CloseHandle (process );
272
- sw_remove_child_at_index (index );
273
- if (status )
274
- * status = exit_code ;
275
- return ret_id ;
276
- }
277
- else if (ret == WAIT_TIMEOUT ) {
278
- /* assert that WNOHANG was specified*/
279
- return 0 ;
280
- }
281
-
282
- DebugBreak ();//fatal
283
- return -1 ;
284
- }
285
-
286
- static void
287
- sw_cleanup_child_zombies () {
288
- int pid = 1 ;
289
- while (pid > 0 ) {
290
- pid = waitpid (-1 , NULL , WNOHANG );
291
- }
292
- }
293
-
294
- struct {
295
- HANDLE timer ;
296
- ULONGLONG ticks_at_start ; /* 0 if timer is not live */
297
- __int64 run_time_sec ; /* time in seconds, timer is set to go off from ticks_at_start */
298
- } timer_info ;
299
-
300
-
301
- VOID CALLBACK
302
- sigalrm_APC (
303
- _In_opt_ LPVOID lpArgToCompletionRoutine ,
304
- _In_ DWORD dwTimerLowValue ,
305
- _In_ DWORD dwTimerHighValue
306
- ) {
307
- sigaddset (& pending_signals , W32_SIGALRM );
308
- }
309
-
310
- unsigned int
311
- sw_alarm (unsigned int sec ) {
312
- LARGE_INTEGER due ;
313
- ULONGLONG sec_passed ;
314
- int ret = 0 ;
315
-
316
- errno = 0 ;
317
- /* cancel any live timer if seconds is 0*/
318
- if (sec == 0 ) {
319
- CancelWaitableTimer (timer_info .timer );
320
- timer_info .ticks_at_start = 0 ;
321
- timer_info .run_time_sec = 0 ;
322
- return 0 ;
323
- }
324
-
325
- due .QuadPart = -10000000LL ; //1 sec in 100 nanosec intervals
326
- due .QuadPart *= sec ;
327
- /* this call resets the timer if it is already active */
328
- if (!SetWaitableTimer (timer_info .timer , & due , 0 , sigalrm_APC , NULL , FALSE)) {
329
- debug ("alram() - ERROR SetWaitableTimer() %d" , GetLastError ());
330
- return 0 ;;
331
- }
332
-
333
- /* if timer was already ative, return when it was due */
334
- if (timer_info .ticks_at_start ) {
335
- sec_passed = (GetTickCount64 () - timer_info .ticks_at_start ) / 1000 ;
336
- if (sec_passed < timer_info .run_time_sec )
337
- ret = timer_info .run_time_sec - sec_passed ;
338
- }
339
- timer_info .ticks_at_start = GetTickCount64 ();
340
- timer_info .run_time_sec = sec ;
341
- return ret ;
342
- }
343
-
344
- static int
345
- sw_init_timer () {
346
- memset (& timer_info , 0 , sizeof (timer_info ));
347
- timer_info .timer = CreateWaitableTimer (NULL , TRUE, NULL );
348
- if (timer_info .timer == NULL ) {
349
- errno = ENOMEM ;
350
- return -1 ;
351
- }
352
- return 0 ;
353
- }
99
+ extern struct _children children ;
354
100
355
101
sighandler_t
356
102
sw_signal (int signum , sighandler_t handler ) {
@@ -377,7 +123,7 @@ sw_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) {
377
123
int
378
124
sw_raise (int sig ) {
379
125
if (sig == W32_SIGSEGV )
380
- raise (SIGSEGV ); /* raise native exception handler*/
126
+ return raise (SIGSEGV ); /* raise native exception handler*/
381
127
382
128
if (sig >= W32_SIGMAX ) {
383
129
errno = EINVAL ;
@@ -432,7 +178,7 @@ sw_process_pending_signals() {
432
178
/* check for expected signals*/
433
179
for (i = 0 ; i < (sizeof (exp ) / sizeof (exp [0 ])); i ++ )
434
180
sigdelset (& pending_tmp , exp [i ]);
435
- if (pending_tmp ) {
181
+ if (pending_tmp ) {
436
182
/* unexpected signals queued up */
437
183
errno = ENOTSUP ;
438
184
DebugBreak ();
@@ -448,6 +194,11 @@ sw_process_pending_signals() {
448
194
sw_raise (exp [i ]);
449
195
sig_int = TRUE;
450
196
}
197
+ else { /* W32_SIG_IGN */
198
+ /* for SIGCHLD process zombies */
199
+ if (exp [i ] == W32_SIGCHLD )
200
+ sw_cleanup_child_zombies ();
201
+ }
451
202
452
203
sigdelset (& pending_tmp , exp [i ]);
453
204
}
@@ -485,8 +236,9 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
485
236
{
486
237
HANDLE all_events [MAXIMUM_WAIT_OBJECTS ];
487
238
DWORD num_all_events ;
239
+ DWORD live_children = children .num_children - children .num_zombies ;
488
240
489
- num_all_events = num_events + children . num_children ;
241
+ num_all_events = num_events + live_children ;
490
242
491
243
if (num_all_events > MAXIMUM_WAIT_OBJECTS ) {
492
244
errno = ENOTSUP ;
@@ -497,8 +249,8 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
497
249
if (pending_signals )
498
250
DebugBreak ();
499
251
500
- memcpy (all_events , children .handles , children . num_children * sizeof (HANDLE ));
501
- memcpy (all_events + children . num_children , events , num_events * sizeof (HANDLE ));
252
+ memcpy (all_events , children .handles , live_children * sizeof (HANDLE ));
253
+ memcpy (all_events + live_children , events , num_events * sizeof (HANDLE ));
502
254
503
255
/* TODO - implement signal catching and handling */
504
256
if (num_all_events ) {
@@ -507,11 +259,8 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
507
259
if ((ret >= WAIT_OBJECT_0 ) && (ret <= WAIT_OBJECT_0 + num_all_events - 1 )) {
508
260
//woken up by event signalled
509
261
/* is this due to a child process going down*/
510
- if (children .num_children && ((ret - WAIT_OBJECT_0 ) < children .num_children )) {
262
+ if (children .num_children && ((ret - WAIT_OBJECT_0 ) < children .num_children ))
511
263
sigaddset (& pending_signals , W32_SIGCHLD );
512
- //errno = EINTR;
513
- //return -1;
514
- }
515
264
}
516
265
else if (ret == WAIT_IO_COMPLETION ) {
517
266
/* APC processed due to IO or signal*/
0 commit comments