initial SIGCHLD implementation

This commit is contained in:
manojampalam 2016-03-14 23:00:27 -07:00
parent 4a991a25a9
commit 238c80b33d
6 changed files with 89 additions and 11 deletions

View File

@ -103,12 +103,13 @@ typedef void(*sighandler_t)(int);
/* /*
* these routines are temporarily defined here to allow transition * these routines are temporarily defined here to allow transition
* from older POSIX wrapper to the newer one. After complete transition * from older POSIX wrapper to the newer one. After complete transition
* these should move to a internal header. * these should be gone or moved to a internal header.
*/ */
int w32_temp_DelChildToWatch(HANDLE processtowatch); int w32_temp_DelChildToWatch(HANDLE processtowatch);
int w32_temp_AddChildToWatch(HANDLE processtowatch); int w32_temp_AddChildToWatch(HANDLE processtowatch);
HANDLE w32_fd_to_handle(int fd); HANDLE w32_fd_to_handle(int fd);
int w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock); int w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock);
int signalio_add_child(HANDLE child);
/* temporary definitions to aid in transition */ /* temporary definitions to aid in transition */
#define WSHELPDelChildToWatch(a) w32_temp_DelChildToWatch((a)) #define WSHELPDelChildToWatch(a) w32_temp_DelChildToWatch((a))

View File

@ -35,6 +35,62 @@
/* signal queue */ /* signal queue */
/* child processes */
#define MAX_CHILDREN 50
struct _children {
HANDLE handles[MAX_CHILDREN];
DWORD num_children;
} children;
void
signalio_initialize() {
memset(&children, 0, sizeof(children));
}
int
signalio_add_child(HANDLE child) {
if (children.num_children == MAX_CHILDREN) {
errno = ENOTSUP;
return -1;
}
children.handles[children.num_children++] = child;
return 0;
}
int
signalio_remove_child_at_index(DWORD index) {
if (index >= children.num_children) {
errno = EINVAL;
return -1;
}
CloseHandle(children.handles[index]);
if ((children.num_children > 1) && (index != (children.num_children - 1))) {
children.handles[index] = children.handles[children.num_children - 1];
}
children.num_children--;
return 0;
}
int
signalio_remove_child(HANDLE child) {
HANDLE* handles = children.handles;
DWORD num_children = children.num_children;
while (num_children) {
if (*handles == child)
return signalio_remove_child_at_index(children.num_children - num_children);
handles++;
num_children--;
}
errno = EINVAL;
return -1;
}
/* /*
* Main wait routine used by all blocking calls. * Main wait routine used by all blocking calls.
* It wakes up on * It wakes up on
@ -49,12 +105,31 @@
int int
wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds) wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
{ {
HANDLE all_events[MAXIMUM_WAIT_OBJECTS];
DWORD num_all_events = num_events + children.num_children;
if (num_all_events > MAXIMUM_WAIT_OBJECTS) {
errno = ENOTSUP;
return -1;
}
memcpy(all_events, children.handles, children.num_children * sizeof(HANDLE));
memcpy(all_events + children.num_children, events, num_events * sizeof(HANDLE));
/* TODO - implement signal catching and handling */ /* TODO - implement signal catching and handling */
if (num_events) { if (num_all_events) {
DWORD ret = WaitForMultipleObjectsEx(num_events, events, FALSE, DWORD ret = WaitForMultipleObjectsEx(num_all_events, all_events, FALSE,
milli_seconds, TRUE); milli_seconds, TRUE);
if ((ret >= WAIT_OBJECT_0) && (ret <= WAIT_OBJECT_0 + num_events - 1)) { if ((ret >= WAIT_OBJECT_0) && (ret <= WAIT_OBJECT_0 + num_all_events - 1)) {
//woken up by event signalled //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)) {
/* TODO - enable this once all direct closes are removed in core code*/
//signalio_remove_child(ret - WAIT_OBJECT_0);
errno = EINTR;
return -1;
}
return 0; return 0;
} }
else if (ret == WAIT_IO_COMPLETION) { else if (ret == WAIT_IO_COMPLETION) {

View File

@ -120,6 +120,7 @@ w32posix_initialize() {
if ((fd_table_initialize() != 0) if ((fd_table_initialize() != 0)
|| (socketio_initialize() != 0)) || (socketio_initialize() != 0))
DebugBreak(); DebugBreak();
signalio_initialize();
} }
void void

View File

@ -121,7 +121,10 @@ long fileio_lseek(struct w32_io* pio, long offset, int origin);
int fileio_isatty(struct w32_io* pio); int fileio_isatty(struct w32_io* pio);
FILE* fileio_fdopen(struct w32_io* pio, const char *mode); FILE* fileio_fdopen(struct w32_io* pio, const char *mode);
/* signal related APIs*/
void signalio_initialize();
//int signalio_add_child(HANDLE child);
//int signalio_remove_child(HANDLE child);
/* /*
* open() flags and modes * open() flags and modes

View File

@ -882,11 +882,8 @@ collect_children(void)
session_close_by_pid(s->pid, status); session_close_by_pid(s->pid, status);
if (s->pid) signalio_remove_child(process);
CloseHandle(process);
/*TODO - fix this*/
//int WSHELPDelChildToWatch (HANDLE processtowatch);
//WSHELPDelChildToWatch (process); // take the process off from watch list in select mux
} }
} }
} while (i > 0); } while (i > 0);

View File

@ -920,6 +920,7 @@ do_exec_no_pty(Session *s, const char *command)
s -> pid = pi.hProcess; s -> pid = pi.hProcess;
s -> processId = pi.dwProcessId; s -> processId = pi.dwProcessId;
signalio_add_child(pi.hProcess);
// Add the child process created to select mux so that during our select data call we know if the process has exited // Add the child process created to select mux so that during our select data call we know if the process has exited
/* TODO - fix thi s*/ /* TODO - fix thi s*/
@ -939,7 +940,7 @@ do_exec_no_pty(Session *s, const char *command)
close(pipein[0]); close(pipein[0]);
close(pipeout[1]); close(pipeout[1]);
close(pipeout[1]); close(pipeerr[1]);
ResumeThread ( pi.hThread ); /* now let cmd shell main thread be active s we have closed all i/o file handle that cmd will use */ ResumeThread ( pi.hThread ); /* now let cmd shell main thread be active s we have closed all i/o file handle that cmd will use */
SetConsoleCtrlHandler(NULL, TRUE); SetConsoleCtrlHandler(NULL, TRUE);