mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-20 12:34:45 +02:00
initial SIGCHLD implementation
This commit is contained in:
parent
4a991a25a9
commit
238c80b33d
@ -103,12 +103,13 @@ typedef void(*sighandler_t)(int);
|
||||
/*
|
||||
* these routines are temporarily defined here to allow 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_AddChildToWatch(HANDLE processtowatch);
|
||||
HANDLE w32_fd_to_handle(int fd);
|
||||
int w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock);
|
||||
int signalio_add_child(HANDLE child);
|
||||
|
||||
/* temporary definitions to aid in transition */
|
||||
#define WSHELPDelChildToWatch(a) w32_temp_DelChildToWatch((a))
|
||||
|
@ -35,6 +35,62 @@
|
||||
|
||||
/* 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.
|
||||
* It wakes up on
|
||||
@ -49,12 +105,31 @@
|
||||
int
|
||||
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 */
|
||||
if (num_events) {
|
||||
DWORD ret = WaitForMultipleObjectsEx(num_events, events, FALSE,
|
||||
if (num_all_events) {
|
||||
DWORD ret = WaitForMultipleObjectsEx(num_all_events, all_events, FALSE,
|
||||
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
|
||||
/* 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;
|
||||
}
|
||||
else if (ret == WAIT_IO_COMPLETION) {
|
||||
|
@ -120,6 +120,7 @@ w32posix_initialize() {
|
||||
if ((fd_table_initialize() != 0)
|
||||
|| (socketio_initialize() != 0))
|
||||
DebugBreak();
|
||||
signalio_initialize();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -121,7 +121,10 @@ long fileio_lseek(struct w32_io* pio, long offset, int origin);
|
||||
int fileio_isatty(struct w32_io* pio);
|
||||
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
|
||||
|
@ -882,11 +882,8 @@ collect_children(void)
|
||||
|
||||
session_close_by_pid(s->pid, status);
|
||||
|
||||
if (s->pid)
|
||||
CloseHandle(process);
|
||||
/*TODO - fix this*/
|
||||
//int WSHELPDelChildToWatch (HANDLE processtowatch);
|
||||
//WSHELPDelChildToWatch (process); // take the process off from watch list in select mux
|
||||
signalio_remove_child(process);
|
||||
|
||||
}
|
||||
}
|
||||
} while (i > 0);
|
||||
|
@ -920,6 +920,7 @@ do_exec_no_pty(Session *s, const char *command)
|
||||
|
||||
s -> pid = pi.hProcess;
|
||||
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
|
||||
/* TODO - fix thi s*/
|
||||
@ -939,7 +940,7 @@ do_exec_no_pty(Session *s, const char *command)
|
||||
|
||||
close(pipein[0]);
|
||||
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 */
|
||||
SetConsoleCtrlHandler(NULL, TRUE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user