Fix to Issue 698 and other misc changes (#208)
Fix to PowerShell/Win32-OpenSSH#698 - Create job object, add ssh-shellhost and ensure all its child process and tied to its lifetime. Other changes include changes to debug* statements in posix adapter that may cause recursion/stack overflow issues.
This commit is contained in:
parent
c8c6b0b04e
commit
b327f0c48a
|
@ -666,7 +666,7 @@ fileio_write(struct w32_io* pio, const void *buf, size_t max_bytes)
|
|||
debug3("write - ERROR:%d on prior unblocking write, io:%p", errno, pio);
|
||||
pio->write_details.error = 0;
|
||||
if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_BROKEN_PIPE)) {
|
||||
debug3("write - ERROR:read end of the pipe closed, io:%p", pio);
|
||||
debug4("write - ERROR:read end of the pipe closed, io:%p", pio);
|
||||
errno = EPIPE;
|
||||
}
|
||||
return -1;
|
||||
|
|
|
@ -215,6 +215,7 @@ HANDLE pipe_in = INVALID_HANDLE_VALUE;
|
|||
HANDLE pipe_out = INVALID_HANDLE_VALUE;
|
||||
HANDLE pipe_err = INVALID_HANDLE_VALUE;
|
||||
HANDLE child = INVALID_HANDLE_VALUE;
|
||||
HANDLE job = NULL;
|
||||
HANDLE hConsoleBuffer = INVALID_HANDLE_VALUE;
|
||||
HANDLE monitor_thread = INVALID_HANDLE_VALUE;
|
||||
HANDLE io_thread = INVALID_HANDLE_VALUE;
|
||||
|
@ -1554,6 +1555,7 @@ wmain(int ac, wchar_t **av)
|
|||
{
|
||||
int pty_requested = 0;
|
||||
wchar_t *cmd = NULL, *cmd_b64 = NULL;
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info;
|
||||
|
||||
_set_invalid_parameter_handler(my_invalid_parameter_handler);
|
||||
if ((ac == 1) || (ac == 2 && wcscmp(av[1], L"-nopty"))) {
|
||||
|
@ -1595,6 +1597,21 @@ wmain(int ac, wchar_t **av)
|
|||
exit(255);
|
||||
}
|
||||
|
||||
/* assign to job object */
|
||||
if ((job = CreateJobObjectW(NULL, NULL)) == NULL) {
|
||||
printf_s("cannot create job object, error: %d", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&job_info, 0, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
|
||||
job_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||
|
||||
if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &job_info, sizeof(job_info)) ||
|
||||
!AssignProcessToJobObject(job, GetCurrentProcess())) {
|
||||
printf_s("cannot associate job object: %d", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pty_requested)
|
||||
return start_with_pty(cmd);
|
||||
else
|
||||
|
|
|
@ -40,7 +40,7 @@ register_child(HANDLE child, DWORD pid)
|
|||
{
|
||||
DWORD first_zombie_index;
|
||||
|
||||
debug3("Register child %p pid %d, %d zombies of %d", child, pid,
|
||||
debug4("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;
|
||||
|
@ -67,7 +67,7 @@ int
|
|||
sw_remove_child_at_index(DWORD index)
|
||||
{
|
||||
DWORD last_non_zombie;
|
||||
debug3("Unregister child at index %d, %d zombies of %d", index,
|
||||
debug4("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)) {
|
||||
|
@ -105,7 +105,7 @@ sw_child_to_zombie(DWORD index)
|
|||
DWORD last_non_zombie, zombie_pid;
|
||||
HANDLE zombie_handle;
|
||||
|
||||
debug3("zombie'ing child at index %d, %d zombies of %d", index,
|
||||
debug4("zombie'ing child at index %d, %d zombies of %d", index,
|
||||
children.num_zombies, children.num_children);
|
||||
|
||||
if (index >= children.num_children) {
|
||||
|
|
|
@ -107,7 +107,8 @@ ReadThread(_In_ LPVOID lpParameter)
|
|||
|
||||
if (!ReadFile(WINHANDLE(pio), pio->read_details.buf,
|
||||
pio->read_details.buf_size, &read_status.transferred, NULL)) {
|
||||
read_status.error = GetLastError();
|
||||
debug4("ReadThread - ReadFile failed, error:%d, io:%p", GetLastError(), pio);
|
||||
read_status.error = GetLastError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -126,7 +127,8 @@ ReadThread(_In_ LPVOID lpParameter)
|
|||
} else {
|
||||
if (!ReadFile(WINHANDLE(pio), pio->read_details.buf,
|
||||
pio->read_details.buf_size, &read_status.transferred, NULL)) {
|
||||
read_status.error = GetLastError();
|
||||
debug4("ReadThread - ReadFile failed, error:%d, io:%p", GetLastError(), pio);
|
||||
read_status.error = GetLastError();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +194,7 @@ WriteThread(_In_ LPVOID lpParameter)
|
|||
struct w32_io* pio = (struct w32_io*)lpParameter;
|
||||
char *respbuf = NULL;
|
||||
size_t resplen = 0;
|
||||
debug5("TermWrite thread, io:%p", pio);
|
||||
debug5("WriteThread thread, io:%p", pio);
|
||||
|
||||
if (FILETYPE(pio) == FILE_TYPE_CHAR) {
|
||||
pio->write_details.buf[write_status.to_transfer] = '\0';
|
||||
|
@ -209,13 +211,13 @@ WriteThread(_In_ LPVOID lpParameter)
|
|||
if (!WriteFile(WINHANDLE(pio), pio->write_details.buf, write_status.to_transfer,
|
||||
&write_status.transferred, NULL)) {
|
||||
write_status.error = GetLastError();
|
||||
debug("WriteThread - ReadFile WriteFile %d, io:%p", GetLastError(), pio);
|
||||
debug4("WriteThread - WriteFile %d, io:%p", GetLastError(), pio);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (0 == QueueUserAPC(WriteAPCProc, main_thread, (ULONG_PTR)pio)) {
|
||||
debug3("TermWrite thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio);
|
||||
debug3("WriteThread thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio);
|
||||
pio->write_details.pending = FALSE;
|
||||
pio->write_details.error = GetLastError();
|
||||
DebugBreak();
|
||||
|
@ -229,13 +231,13 @@ int
|
|||
syncio_initiate_write(struct w32_io* pio, DWORD num_bytes)
|
||||
{
|
||||
HANDLE write_thread;
|
||||
debug5("TermWrite initiate io:%p", pio);
|
||||
debug5("syncio_initiate_write initiate io:%p", pio);
|
||||
memset(&write_status, 0, sizeof(write_status));
|
||||
write_status.to_transfer = num_bytes;
|
||||
write_thread = CreateThread(NULL, 0, WriteThread, pio, 0, NULL);
|
||||
if (write_thread == NULL) {
|
||||
errno = errno_from_Win32LastError();
|
||||
debug3("TermWrite initiate - ERROR CreateThread %d, io:%p", GetLastError(), pio);
|
||||
debug3("syncio_initiate_write initiate - ERROR CreateThread %d, io:%p", GetLastError(), pio);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ w32_socket(int domain, int type, int protocol)
|
|||
}
|
||||
|
||||
fd_table_set(pio, min_index);
|
||||
debug3("socket:%d, socktype:%d, io:%p, fd:%d ", pio->sock, type, pio, min_index);
|
||||
debug4("socket:%d, socktype:%d, io:%p, fd:%d ", pio->sock, type, pio, min_index);
|
||||
return min_index;
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,7 @@ w32_accept(int fd, struct sockaddr* addr, int* addrlen)
|
|||
|
||||
pio->type = SOCK_FD;
|
||||
fd_table_set(pio, min_index);
|
||||
debug3("socket:%d, io:%p, fd:%d ", pio->sock, pio, min_index);
|
||||
debug4("socket:%d, io:%p, fd:%d ", pio->sock, pio, min_index);
|
||||
return min_index;
|
||||
}
|
||||
|
||||
|
@ -404,7 +404,7 @@ w32_pipe(int *pfds)
|
|||
fd_table_set(pio[1], write_index);
|
||||
pfds[0] = read_index;
|
||||
pfds[1] = write_index;
|
||||
debug3("pipe - r-h:%d,io:%p,fd:%d w-h:%d,io:%p,fd:%d",
|
||||
debug4("pipe - r-h:%d,io:%p,fd:%d w-h:%d,io:%p,fd:%d",
|
||||
pio[0]->handle, pio[0], read_index, pio[1]->handle, pio[1], write_index);
|
||||
|
||||
return 0;
|
||||
|
@ -434,7 +434,7 @@ w32_open(const char *pathname, int flags, ... /* arg */)
|
|||
|
||||
pio->type = NONSOCK_FD;
|
||||
fd_table_set(pio, min_index);
|
||||
debug3("open - handle:%p, io:%p, fd:%d", pio->handle, pio, min_index);
|
||||
debug4("open - handle:%p, io:%p, fd:%d", pio->handle, pio, min_index);
|
||||
debug5("open - path:%s", pathname);
|
||||
return min_index;
|
||||
}
|
||||
|
@ -532,7 +532,7 @@ w32_close(int fd)
|
|||
|
||||
pio = fd_table.w32_ios[fd];
|
||||
|
||||
debug3("close - io:%p, type:%d, fd:%d, table_index:%d", pio, pio->type, fd,
|
||||
debug4("close - io:%p, type:%d, fd:%d, table_index:%d", pio, pio->type, fd,
|
||||
pio->table_index);
|
||||
|
||||
if (pio->type == SOCK_FD)
|
||||
|
@ -731,7 +731,7 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
|||
|
||||
if (timeout != NULL) {
|
||||
if (timeout_ms < ticks_spent) {
|
||||
debug3("select - timing out");
|
||||
debug4("select - timing out");
|
||||
break;
|
||||
}
|
||||
time_rem = timeout_ms - (ticks_spent & 0xffffffff);
|
||||
|
|
Loading…
Reference in New Issue