@@ -70,17 +70,19 @@ sw_init_signal_handler_table() {
70
70
#define MAX_CHILDREN 50
71
71
struct _children {
72
72
HANDLE handles [MAX_CHILDREN ];
73
- // DWORD process_id[MAX_CHILDREN];
73
+ DWORD process_id [MAX_CHILDREN ];
74
74
DWORD num_children ;
75
75
} children ;
76
76
77
77
int
78
- sw_add_child (HANDLE child ) {
78
+ sw_add_child (HANDLE child , DWORD pid ) {
79
79
if (children .num_children == MAX_CHILDREN ) {
80
80
errno = ENOTSUP ;
81
81
return -1 ;
82
82
}
83
- children .handles [children .num_children ++ ] = child ;
83
+ children .handles [children .num_children ] = child ;
84
+ children .process_id [children .num_children ] = pid ;
85
+ children .num_children ++ ;
84
86
return 0 ;
85
87
}
86
88
@@ -100,7 +102,6 @@ sw_remove_child_at_index(DWORD index) {
100
102
return 0 ;
101
103
}
102
104
103
-
104
105
int
105
106
sw_remove_child (HANDLE child ) {
106
107
HANDLE * handles = children .handles ;
@@ -117,6 +118,90 @@ sw_remove_child(HANDLE child) {
117
118
return -1 ;
118
119
}
119
120
121
+ int waitpid (int pid , int * status , int options ) {
122
+ DWORD index , ret , ret_id , exit_code , timeout = 0 ;
123
+ HANDLE process = NULL ;
124
+
125
+ if (options & (~WNOHANG )) {
126
+ errno = ENOTSUP ;
127
+ DebugBreak ();
128
+ return -1 ;
129
+ }
130
+
131
+ if ((pid < -1 ) || (pid == 0 )) {
132
+ errno = ENOTSUP ;
133
+ DebugBreak ();
134
+ return -1 ;
135
+ }
136
+
137
+ if (children .num_children == 0 ) {
138
+ errno = ECHILD ;
139
+ return -1 ;
140
+ }
141
+
142
+ if (pid > 0 ) {
143
+ if (options != 0 ) {
144
+ errno = ENOTSUP ;
145
+ DebugBreak ();
146
+ return -1 ;
147
+ }
148
+ /* find entry in table */
149
+ for (index = 0 ; index < children .num_children ; index ++ )
150
+ if (children .process_id [index ] == pid )
151
+ break ;
152
+
153
+ if (index == children .num_children ) {
154
+ errno = ECHILD ;
155
+ return -1 ;
156
+ }
157
+
158
+ process = children .handles [index ];
159
+ ret = WaitForSingleObject (process , INFINITE );
160
+ if (ret != WAIT_OBJECT_0 )
161
+ DebugBreak ();//fatal
162
+
163
+ ret_id = children .process_id [index ];
164
+ GetExitCodeProcess (process , & exit_code );
165
+ CloseHandle (process );
166
+ sw_remove_child_at_index (index );
167
+ if (status )
168
+ * status = exit_code ;
169
+ return ret_id ;
170
+ }
171
+
172
+ /* pid = -1*/
173
+ timeout = INFINITE ;
174
+ if (options & WNOHANG )
175
+ timeout = 0 ;
176
+ ret = WaitForMultipleObjects (children .num_children , children .handles , FALSE, timeout );
177
+ if ((ret >= WAIT_OBJECT_0 ) && (ret < (WAIT_OBJECT_0 + children .num_children ))) {
178
+ index = ret - WAIT_OBJECT_0 ;
179
+ process = children .handles [index ];
180
+ ret_id = children .process_id [index ];
181
+ GetExitCodeProcess (process , & exit_code );
182
+ CloseHandle (process );
183
+ sw_remove_child_at_index (index );
184
+ if (status )
185
+ * status = exit_code ;
186
+ return ret_id ;
187
+ }
188
+ else if (ret == WAIT_TIMEOUT ) {
189
+ /* assert that WNOHANG was specified*/
190
+ return 0 ;
191
+ }
192
+
193
+ DebugBreak ();//fatal
194
+ return -1 ;
195
+ }
196
+
197
+ static void
198
+ sw_cleanup_child_zombies () {
199
+ int pid = 1 ;
200
+ while (pid > 0 ) {
201
+ pid = waitpid (-1 , NULL , WNOHANG );
202
+ }
203
+ }
204
+
120
205
struct {
121
206
HANDLE timer ;
122
207
ULONGLONG ticks_at_start ; /* 0 if timer is not live */
@@ -223,7 +308,7 @@ sw_raise(int sig) {
223
308
/* execute any default handlers */
224
309
switch (sig ) {
225
310
case W32_SIGCHLD :
226
- /*TODO - execute sigchild default handler */
311
+ sw_cleanup_child_zombies ();
227
312
break ;
228
313
case W32_SIGINT :
229
314
/* TODO - execute sigint default handler */
@@ -274,9 +359,6 @@ sw_process_pending_signals() {
274
359
sw_raise (exp [i ]);
275
360
sig_int = TRUE;
276
361
}
277
- else {/* disposition is W32_SIG_IGN */
278
- /* TODO for SIG_CHLD - do clean up of Zombies */
279
- }
280
362
281
363
sigdelset (& pending_tmp , exp [i ]);
282
364
}
313
395
wait_for_any_event (HANDLE * events , int num_events , DWORD milli_seconds )
314
396
{
315
397
HANDLE all_events [MAXIMUM_WAIT_OBJECTS ];
316
- DWORD num_all_events = num_events + children .num_children ;
398
+ DWORD num_all_events ;
399
+
400
+ num_all_events = num_events + children .num_children ;
317
401
318
402
if (num_all_events > MAXIMUM_WAIT_OBJECTS ) {
319
403
errno = ENOTSUP ;
@@ -335,11 +419,9 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
335
419
//woken up by event signalled
336
420
/* is this due to a child process going down*/
337
421
if (children .num_children && ((ret - WAIT_OBJECT_0 ) < children .num_children )) {
338
- /* TODO - enable this once all direct closes are removed in core code*/
339
- //sigaddset(&pending_signals, W32_SIGCHLD);
340
- //sw_remove_child(ret - WAIT_OBJECT_0);
341
- errno = EINTR ;
342
- return -1 ;
422
+ sigaddset (& pending_signals , W32_SIGCHLD );
423
+ //errno = EINTR;
424
+ //return -1;
343
425
}
344
426
}
345
427
else if (ret == WAIT_IO_COMPLETION ) {
0 commit comments