diff --git a/contrib/win32/openssh/win32iocompat.vcxproj b/contrib/win32/openssh/win32iocompat.vcxproj
index 179cd50..43bedc5 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj
+++ b/contrib/win32/openssh/win32iocompat.vcxproj
@@ -147,7 +147,9 @@
-
+
+
+
@@ -163,8 +165,9 @@
-
-
+
+
+
diff --git a/contrib/win32/openssh/win32iocompat.vcxproj.filters b/contrib/win32/openssh/win32iocompat.vcxproj.filters
index ab0c612..31d0e0d 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj.filters
+++ b/contrib/win32/openssh/win32iocompat.vcxproj.filters
@@ -7,7 +7,9 @@
-
+
+
+
@@ -53,6 +55,7 @@
inc
+
diff --git a/contrib/win32/win32compat/signal.c b/contrib/win32/win32compat/signal.c
index 2c1507f..3a5f65e 100644
--- a/contrib/win32/win32compat/signal.c
+++ b/contrib/win32/win32compat/signal.c
@@ -31,7 +31,7 @@
#include "w32fd.h"
#include
#include
-#include "inc\defs.h"
+#include "signal_internal.h"
/* pending signals to be processed */
sigset_t pending_signals;
@@ -96,261 +96,7 @@ sw_init_signal_handler_table() {
memset(sig_handlers, 0, sizeof(sig_handlers));
}
-/* child processes */
-#define MAX_CHILDREN 50
-struct _children {
- HANDLE handles[MAX_CHILDREN];
- DWORD process_id[MAX_CHILDREN];
- /* total children */
- DWORD num_children;
- /* #zombies */
- /* (num_chileren - zombies) are live children */
- DWORD num_zombies;
-} children;
-
-int
-sw_add_child(HANDLE child, DWORD pid) {
- DWORD first_zombie_index;
-
- debug("Register child %p pid %d, %d zombies of %d", child, pid,
- children.num_zombies, children.num_children);
- if (children.num_children == MAX_CHILDREN) {
- errno = ENOMEM;
- return -1;
- }
- if (children.num_zombies) {
- first_zombie_index = children.num_children - children.num_zombies;
- children.handles[children.num_children] = children.handles[first_zombie_index];
- children.process_id[children.num_children] = children.handles[first_zombie_index];
-
- children.handles[first_zombie_index] = child;
- children.process_id[first_zombie_index] = pid;
- }
- else {
- children.handles[children.num_children] = child;
- children.process_id[children.num_children] = pid;
- }
-
-
- children.num_children++;
- return 0;
-}
-
-int
-sw_remove_child_at_index(DWORD index) {
- DWORD last_non_zombie;
-
- debug("Unregister child at index %d, %d zombies of %d", index,
- children.num_zombies, children.num_children);
-
- if ((index >= children.num_children)
- || (children.num_children == 0) ){
- errno = EINVAL;
- return -1;
- }
-
- CloseHandle(children.handles[index]);
- if (children.num_zombies == 0) {
- children.handles[index] = children.handles[children.num_children - 1];
- children.process_id[index] = children.process_id[children.num_children - 1];
- }
- else {
- /* if its a zombie */
- if (index >= (children.num_children - children.num_zombies)) {
- children.handles[index] = children.handles[children.num_children - 1];
- children.process_id[index] = children.handles[children.num_children - 1];
- children.num_zombies--;
- }
- else {
- last_non_zombie = children.num_children - children.num_zombies - 1;
- children.handles[index] = children.handles[last_non_zombie];
- children.process_id[index] = children.process_id[last_non_zombie];
-
- children.handles[last_non_zombie] = children.handles[children.num_children - 1];
- children.process_id[last_non_zombie] = children.handles[children.num_children - 1];
- }
- }
-
- children.num_children--;
- return 0;
-}
-
-int
-sw_child_to_zombie(DWORD index) {
- DWORD last_non_zombie;
-
- debug("zombie'ing child at index %d, %d zombies of %d", index,
- children.num_zombies, children.num_children);
-
- if (index >= children.num_children) {
- errno = EINVAL;
- return -1;
- }
-
- /* TODO - turn child to zombie*/
- return 0;
-}
-
-int
-sw_remove_child(HANDLE child) {
- HANDLE* handles = children.handles;
- DWORD num_children = children.num_children;
-
- while (num_children) {
- if (*handles == child)
- return sw_remove_child_at_index(children.num_children - num_children);
- handles++;
- num_children--;
- }
-
- errno = EINVAL;
- return -1;
-}
-
-int waitpid(int pid, int *status, int options) {
- DWORD index, ret, ret_id, exit_code, timeout = 0;
- HANDLE process = NULL;
-
- if (options & (~WNOHANG)) {
- errno = ENOTSUP;
- DebugBreak();
- return -1;
- }
-
- if ((pid < -1) || (pid == 0)) {
- errno = ENOTSUP;
- DebugBreak();
- return -1;
- }
-
- if (children.num_children == 0) {
- errno = ECHILD;
- return -1;
- }
-
- if (pid > 0) {
- if (options != 0) {
- errno = ENOTSUP;
- DebugBreak();
- return -1;
- }
- /* find entry in table */
- for (index = 0; index < children.num_children; index++)
- if (children.process_id[index] == pid)
- break;
-
- if (index == children.num_children) {
- errno = ECHILD;
- return -1;
- }
-
- process = children.handles[index];
- ret = WaitForSingleObject(process, INFINITE);
- if (ret != WAIT_OBJECT_0)
- DebugBreak();//fatal
-
- ret_id = children.process_id[index];
- GetExitCodeProcess(process, &exit_code);
- CloseHandle(process);
- sw_remove_child_at_index(index);
- if (status)
- *status = exit_code;
- return ret_id;
- }
-
- /* pid = -1*/
- timeout = INFINITE;
- if (options & WNOHANG)
- timeout = 0;
- ret = WaitForMultipleObjects(children.num_children, children.handles, FALSE, timeout);
- if ((ret >= WAIT_OBJECT_0) && (ret < (WAIT_OBJECT_0 + children.num_children))) {
- index = ret - WAIT_OBJECT_0;
- process = children.handles[index];
- ret_id = children.process_id[index];
- GetExitCodeProcess(process, &exit_code);
- CloseHandle(process);
- sw_remove_child_at_index(index);
- if (status)
- *status = exit_code;
- return ret_id;
- }
- else if (ret == WAIT_TIMEOUT) {
- /* assert that WNOHANG was specified*/
- return 0;
- }
-
- DebugBreak();//fatal
- return -1;
-}
-
-static void
-sw_cleanup_child_zombies() {
- int pid = 1;
- while (pid > 0) {
- pid = waitpid(-1, NULL, WNOHANG);
- }
-}
-
-struct {
- HANDLE timer;
- ULONGLONG ticks_at_start; /* 0 if timer is not live */
- __int64 run_time_sec; /* time in seconds, timer is set to go off from ticks_at_start */
-} timer_info;
-
-
-VOID CALLBACK
-sigalrm_APC(
- _In_opt_ LPVOID lpArgToCompletionRoutine,
- _In_ DWORD dwTimerLowValue,
- _In_ DWORD dwTimerHighValue
- ) {
- sigaddset(&pending_signals, W32_SIGALRM);
-}
-
-unsigned int
-sw_alarm(unsigned int sec) {
- LARGE_INTEGER due;
- ULONGLONG sec_passed;
- int ret = 0;
-
- errno = 0;
- /* cancel any live timer if seconds is 0*/
- if (sec == 0) {
- CancelWaitableTimer(timer_info.timer);
- timer_info.ticks_at_start = 0;
- timer_info.run_time_sec = 0;
- return 0;
- }
-
- due.QuadPart = -10000000LL; //1 sec in 100 nanosec intervals
- due.QuadPart *= sec;
- /* this call resets the timer if it is already active */
- if (!SetWaitableTimer(timer_info.timer, &due, 0, sigalrm_APC, NULL, FALSE)) {
- debug("alram() - ERROR SetWaitableTimer() %d", GetLastError());
- return 0;;
- }
-
- /* if timer was already ative, return when it was due */
- if (timer_info.ticks_at_start) {
- sec_passed = (GetTickCount64() - timer_info.ticks_at_start) / 1000;
- if (sec_passed < timer_info.run_time_sec)
- ret = timer_info.run_time_sec - sec_passed;
- }
- timer_info.ticks_at_start = GetTickCount64();
- timer_info.run_time_sec = sec;
- return ret;
-}
-
-static int
-sw_init_timer() {
- memset(&timer_info, 0, sizeof(timer_info));
- timer_info.timer = CreateWaitableTimer(NULL, TRUE, NULL);
- if (timer_info.timer == NULL) {
- errno = ENOMEM;
- return -1;
- }
- return 0;
-}
+extern struct _children children;
sighandler_t
sw_signal(int signum, sighandler_t handler) {
@@ -377,7 +123,7 @@ sw_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) {
int
sw_raise(int sig) {
if (sig == W32_SIGSEGV)
- raise(SIGSEGV); /* raise native exception handler*/
+ return raise(SIGSEGV); /* raise native exception handler*/
if (sig >= W32_SIGMAX) {
errno = EINVAL;
@@ -432,7 +178,7 @@ sw_process_pending_signals() {
/* check for expected signals*/
for (i = 0; i < (sizeof(exp) / sizeof(exp[0])); i++)
sigdelset(&pending_tmp, exp[i]);
- if (pending_tmp) {
+ if (pending_tmp) {
/* unexpected signals queued up */
errno = ENOTSUP;
DebugBreak();
@@ -448,6 +194,11 @@ sw_process_pending_signals() {
sw_raise(exp[i]);
sig_int = TRUE;
}
+ else { /* W32_SIG_IGN */
+ /* for SIGCHLD process zombies */
+ if (exp[i] == W32_SIGCHLD)
+ sw_cleanup_child_zombies();
+ }
sigdelset(&pending_tmp, exp[i]);
}
@@ -485,8 +236,9 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
{
HANDLE all_events[MAXIMUM_WAIT_OBJECTS];
DWORD num_all_events;
+ DWORD live_children = children.num_children - children.num_zombies;
- num_all_events = num_events + children.num_children;
+ num_all_events = num_events + live_children;
if (num_all_events > MAXIMUM_WAIT_OBJECTS) {
errno = ENOTSUP;
@@ -497,8 +249,8 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
if (pending_signals)
DebugBreak();
- memcpy(all_events, children.handles, children.num_children * sizeof(HANDLE));
- memcpy(all_events + children.num_children, events, num_events * sizeof(HANDLE));
+ memcpy(all_events, children.handles, live_children * sizeof(HANDLE));
+ memcpy(all_events + live_children, events, num_events * sizeof(HANDLE));
/* TODO - implement signal catching and handling */
if (num_all_events) {
@@ -507,11 +259,8 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
if ((ret >= WAIT_OBJECT_0) && (ret <= WAIT_OBJECT_0 + num_all_events - 1)) {
//woken up by event signalled
/* is this due to a child process going down*/
- if (children.num_children && ((ret - WAIT_OBJECT_0) < children.num_children)) {
+ if (children.num_children && ((ret - WAIT_OBJECT_0) < children.num_children))
sigaddset(&pending_signals, W32_SIGCHLD);
- //errno = EINTR;
- //return -1;
- }
}
else if (ret == WAIT_IO_COMPLETION) {
/* APC processed due to IO or signal*/
diff --git a/contrib/win32/win32compat/signal_internal.h b/contrib/win32/win32compat/signal_internal.h
new file mode 100644
index 0000000..d9a3b4e
--- /dev/null
+++ b/contrib/win32/win32compat/signal_internal.h
@@ -0,0 +1,35 @@
+#include
+#include "inc\defs.h"
+
+
+int sw_initialize();
+sighandler_t sw_signal(int signum, sighandler_t handler);
+int sw_sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
+int sw_raise(int sig);
+int sw_kill(int pid, int sig);
+
+/* child processes */
+#define MAX_CHILDREN 50
+struct _children {
+ HANDLE handles[MAX_CHILDREN];
+ DWORD process_id[MAX_CHILDREN];
+ /* total children */
+ DWORD num_children;
+ /* #zombies */
+ /* (num_chileren - zombies) are live children */
+ DWORD num_zombies;
+};
+
+int sw_add_child(HANDLE child, DWORD pid);
+int sw_remove_child_at_index(DWORD index);
+int sw_child_to_zombie(DWORD index);
+int sw_remove_child(HANDLE child);
+void sw_cleanup_child_zombies();
+
+struct _timer_info {
+ HANDLE timer;
+ ULONGLONG ticks_at_start; /* 0 if timer is not live */
+ __int64 run_time_sec; /* time in seconds, timer is set to go off from ticks_at_start */
+};
+int sw_init_timer();
+unsigned int sw_alarm(unsigned int seconds);
\ No newline at end of file
diff --git a/contrib/win32/win32compat/signal_sigalrm.c b/contrib/win32/win32compat/signal_sigalrm.c
new file mode 100644
index 0000000..d3cc448
--- /dev/null
+++ b/contrib/win32/win32compat/signal_sigalrm.c
@@ -0,0 +1,88 @@
+/*
+* Author: Manoj Ampalam
+*
+* Copyright(c) 2015 Microsoft Corp.
+* All rights reserved
+*
+* Helper routines to support SIGALRM
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met :
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and / or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "signal_internal.h"
+
+struct _timer_info timer_info;
+extern sigset_t pending_signals;
+
+static VOID CALLBACK
+sigalrm_APC(
+ _In_opt_ LPVOID lpArgToCompletionRoutine,
+ _In_ DWORD dwTimerLowValue,
+ _In_ DWORD dwTimerHighValue
+ ) {
+ sigaddset(&pending_signals, W32_SIGALRM);
+}
+
+unsigned int
+sw_alarm(unsigned int sec) {
+ LARGE_INTEGER due;
+ ULONGLONG sec_passed;
+ int ret = 0;
+
+ errno = 0;
+ /* cancel any live timer if seconds is 0*/
+ if (sec == 0) {
+ CancelWaitableTimer(timer_info.timer);
+ timer_info.ticks_at_start = 0;
+ timer_info.run_time_sec = 0;
+ return 0;
+ }
+
+ due.QuadPart = -10000000LL; //1 sec in 100 nanosec intervals
+ due.QuadPart *= sec;
+ /* this call resets the timer if it is already active */
+ if (!SetWaitableTimer(timer_info.timer, &due, 0, sigalrm_APC, NULL, FALSE)) {
+ debug("alram() - ERROR SetWaitableTimer() %d", GetLastError());
+ return 0;;
+ }
+
+ /* if timer was already ative, return when it was due */
+ if (timer_info.ticks_at_start) {
+ sec_passed = (GetTickCount64() - timer_info.ticks_at_start) / 1000;
+ if (sec_passed < timer_info.run_time_sec)
+ ret = timer_info.run_time_sec - sec_passed;
+ }
+ timer_info.ticks_at_start = GetTickCount64();
+ timer_info.run_time_sec = sec;
+ return ret;
+}
+
+int
+sw_init_timer() {
+ memset(&timer_info, 0, sizeof(timer_info));
+ timer_info.timer = CreateWaitableTimer(NULL, TRUE, NULL);
+ if (timer_info.timer == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/contrib/win32/win32compat/signal_sigchld.c b/contrib/win32/win32compat/signal_sigchld.c
new file mode 100644
index 0000000..aee8d38
--- /dev/null
+++ b/contrib/win32/win32compat/signal_sigchld.c
@@ -0,0 +1,228 @@
+/*
+* Author: Manoj Ampalam
+*
+* Copyright(c) 2015 Microsoft Corp.
+* All rights reserved
+*
+* Helper routines to support SIGCLD and related routines implementation
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met :
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and / or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "signal_internal.h"
+
+struct _children children;
+
+int
+sw_add_child(HANDLE child, DWORD pid) {
+ DWORD first_zombie_index;
+
+ debug("Register child %p pid %d, %d zombies of %d", child, pid,
+ children.num_zombies, children.num_children);
+ if (children.num_children == MAX_CHILDREN) {
+ errno = ENOMEM;
+ return -1;
+ }
+ if (children.num_zombies) {
+ first_zombie_index = children.num_children - children.num_zombies;
+ children.handles[children.num_children] = children.handles[first_zombie_index];
+ children.process_id[children.num_children] = children.process_id[first_zombie_index];
+
+ children.handles[first_zombie_index] = child;
+ children.process_id[first_zombie_index] = pid;
+ }
+ else {
+ children.handles[children.num_children] = child;
+ children.process_id[children.num_children] = pid;
+ }
+
+
+ children.num_children++;
+ return 0;
+}
+
+int
+sw_remove_child_at_index(DWORD index) {
+ DWORD last_non_zombie;
+
+ debug("Unregister child at index %d, %d zombies of %d", index,
+ children.num_zombies, children.num_children);
+
+ if ((index >= children.num_children)
+ || (children.num_children == 0)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ CloseHandle(children.handles[index]);
+ if (children.num_zombies == 0) {
+ children.handles[index] = children.handles[children.num_children - 1];
+ children.process_id[index] = children.process_id[children.num_children - 1];
+ }
+ else {
+ /* if its a zombie */
+ if (index >= (children.num_children - children.num_zombies)) {
+ children.handles[index] = children.handles[children.num_children - 1];
+ children.process_id[index] = children.process_id[children.num_children - 1];
+ children.num_zombies--;
+ }
+ else {
+ last_non_zombie = children.num_children - children.num_zombies - 1;
+ children.handles[index] = children.handles[last_non_zombie];
+ children.process_id[index] = children.process_id[last_non_zombie];
+
+ children.handles[last_non_zombie] = children.handles[children.num_children - 1];
+ children.process_id[last_non_zombie] = children.process_id[children.num_children - 1];
+ }
+ }
+
+ children.num_children--;
+ return 0;
+}
+
+int
+sw_child_to_zombie(DWORD index) {
+ DWORD last_non_zombie, last_child, zombie_pid;
+ HANDLE zombie_handle;
+
+ debug("zombie'ing child at index %d, %d zombies of %d", index,
+ children.num_zombies, children.num_children);
+
+ if (index >= children.num_children) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ zombie_pid = children.process_id[index];
+ zombie_handle = children.handles[index];
+ last_non_zombie = children.num_children - children.num_zombies - 1;
+ last_child = children.num_children - 1;
+
+ children.handles[index] = children.handles[last_non_zombie];
+ children.process_id[index] = children.process_id[last_non_zombie];
+
+ children.handles[last_non_zombie] = children.handles[index];
+ children.process_id[last_non_zombie] = children.process_id[index];
+
+ children.num_zombies++;
+ return 0;
+}
+
+int
+sw_remove_child(HANDLE child) {
+ HANDLE* handles = children.handles;
+ DWORD num_children = children.num_children;
+
+ while (num_children) {
+ if (*handles == child)
+ return sw_remove_child_at_index(children.num_children - num_children);
+ handles++;
+ num_children--;
+ }
+
+ errno = EINVAL;
+ return -1;
+}
+
+int waitpid(int pid, int *status, int options) {
+ DWORD index, ret, ret_id, exit_code, timeout = 0;
+ HANDLE process = NULL;
+
+ if (options & (~WNOHANG)) {
+ errno = ENOTSUP;
+ DebugBreak();
+ return -1;
+ }
+
+ if ((pid < -1) || (pid == 0)) {
+ errno = ENOTSUP;
+ DebugBreak();
+ return -1;
+ }
+
+ if (children.num_children == 0) {
+ errno = ECHILD;
+ return -1;
+ }
+
+ if (pid > 0) {
+ if (options != 0) {
+ errno = ENOTSUP;
+ DebugBreak();
+ return -1;
+ }
+ /* find entry in table */
+ for (index = 0; index < children.num_children; index++)
+ if (children.process_id[index] == pid)
+ break;
+
+ if (index == children.num_children) {
+ errno = ECHILD;
+ return -1;
+ }
+
+ process = children.handles[index];
+ ret = WaitForSingleObject(process, INFINITE);
+ if (ret != WAIT_OBJECT_0)
+ DebugBreak();//fatal
+
+ ret_id = children.process_id[index];
+ GetExitCodeProcess(process, &exit_code);
+ CloseHandle(process);
+ sw_remove_child_at_index(index);
+ if (status)
+ *status = exit_code;
+ return ret_id;
+ }
+
+ /* pid = -1*/
+ timeout = INFINITE;
+ if (options & WNOHANG)
+ timeout = 0;
+ ret = WaitForMultipleObjects(children.num_children, children.handles, FALSE, timeout);
+ if ((ret >= WAIT_OBJECT_0) && (ret < (WAIT_OBJECT_0 + children.num_children))) {
+ index = ret - WAIT_OBJECT_0;
+ process = children.handles[index];
+ ret_id = children.process_id[index];
+ GetExitCodeProcess(process, &exit_code);
+ CloseHandle(process);
+ sw_remove_child_at_index(index);
+ if (status)
+ *status = exit_code;
+ return ret_id;
+ }
+ else if (ret == WAIT_TIMEOUT) {
+ /* TODO - assert that WNOHANG was specified*/
+ return 0;
+ }
+
+ DebugBreak();//fatal
+ return -1;
+}
+
+void
+sw_cleanup_child_zombies() {
+ int pid = 1;
+ while (pid > 0) {
+ pid = waitpid(-1, NULL, WNOHANG);
+ }
+}
\ No newline at end of file
diff --git a/contrib/win32/win32compat/w32fd.h b/contrib/win32/win32compat/w32fd.h
index 4925969..e02d739 100644
--- a/contrib/win32/win32compat/w32fd.h
+++ b/contrib/win32/win32compat/w32fd.h
@@ -121,16 +121,6 @@ FILE* fileio_fdopen(struct w32_io* pio, const char *mode);
/* terminal io specific versions */
int termio_close(struct w32_io* pio);
-/* signal related APIs*/
-int sw_initialize();
-int sw_add_child(HANDLE child, DWORD pid);
-int sw_remove_child(HANDLE child);
-unsigned int sw_alarm(unsigned int seconds);
-sighandler_t sw_signal(int signum, sighandler_t handler);
-int sw_sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
-int sw_raise(int sig);
-int sw_kill(int pid, int sig);
-
/*
* open() flags and modes
* all commented out macros are defined in fcntl.h