Cygwin: pty: Add error handling in setup_pseudoconsole().
- In setup_pseudoconsole(), many error handling was omitted. This patch adds missing error handling.
This commit is contained in:
parent
9b51beeb2a
commit
8cb20fa5d3
@ -3413,7 +3413,10 @@ fhandler_pty_master::setup_pseudoconsole ()
|
|||||||
process in a pseudo console and get them from the helper.
|
process in a pseudo console and get them from the helper.
|
||||||
Slave process will attach to the pseudo console in the
|
Slave process will attach to the pseudo console in the
|
||||||
helper process using AttachConsole(). */
|
helper process using AttachConsole(). */
|
||||||
COORD size = {80, 25};
|
COORD size = {
|
||||||
|
(SHORT) get_ttyp ()->winsize.ws_col,
|
||||||
|
(SHORT) get_ttyp ()->winsize.ws_row
|
||||||
|
};
|
||||||
CreatePipe (&from_master, &to_slave, &sec_none, 0);
|
CreatePipe (&from_master, &to_slave, &sec_none, 0);
|
||||||
SetLastError (ERROR_SUCCESS);
|
SetLastError (ERROR_SUCCESS);
|
||||||
HRESULT res = CreatePseudoConsole (size, from_master, to_master,
|
HRESULT res = CreatePseudoConsole (size, from_master, to_master,
|
||||||
@ -3423,12 +3426,7 @@ fhandler_pty_master::setup_pseudoconsole ()
|
|||||||
if (res != S_OK)
|
if (res != S_OK)
|
||||||
system_printf ("CreatePseudoConsole() failed. %08x\n",
|
system_printf ("CreatePseudoConsole() failed. %08x\n",
|
||||||
GetLastError ());
|
GetLastError ());
|
||||||
CloseHandle (from_master);
|
goto fallback;
|
||||||
CloseHandle (to_slave);
|
|
||||||
from_master = from_master_cyg;
|
|
||||||
to_slave = NULL;
|
|
||||||
get_ttyp ()->h_pseudo_console = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If master process is running as service, attaching to
|
/* If master process is running as service, attaching to
|
||||||
@ -3439,69 +3437,82 @@ fhandler_pty_master::setup_pseudoconsole ()
|
|||||||
if (is_running_as_service ())
|
if (is_running_as_service ())
|
||||||
get_ttyp ()->attach_pcon_in_fork = true;
|
get_ttyp ()->attach_pcon_in_fork = true;
|
||||||
|
|
||||||
SIZE_T bytesRequired;
|
|
||||||
InitializeProcThreadAttributeList (NULL, 2, 0, &bytesRequired);
|
|
||||||
STARTUPINFOEXW si_helper;
|
STARTUPINFOEXW si_helper;
|
||||||
ZeroMemory (&si_helper, sizeof (si_helper));
|
HANDLE hello, goodbye;
|
||||||
si_helper.StartupInfo.cb = sizeof (STARTUPINFOEXW);
|
|
||||||
si_helper.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)
|
|
||||||
HeapAlloc (GetProcessHeap (), 0, bytesRequired);
|
|
||||||
InitializeProcThreadAttributeList (si_helper.lpAttributeList,
|
|
||||||
2, 0, &bytesRequired);
|
|
||||||
UpdateProcThreadAttribute (si_helper.lpAttributeList,
|
|
||||||
0,
|
|
||||||
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
|
|
||||||
get_ttyp ()->h_pseudo_console,
|
|
||||||
sizeof (get_ttyp ()->h_pseudo_console),
|
|
||||||
NULL, NULL);
|
|
||||||
HANDLE hello = CreateEvent (&sec_none, true, false, NULL);
|
|
||||||
HANDLE goodbye = CreateEvent (&sec_none, true, false, NULL);
|
|
||||||
/* Create a pipe for receiving pseudo console handles */
|
|
||||||
HANDLE hr, hw;
|
HANDLE hr, hw;
|
||||||
CreatePipe (&hr, &hw, &sec_none, 0);
|
|
||||||
/* Inherit only handles which are needed by helper. */
|
|
||||||
HANDLE handles_to_inherit[] = {hello, goodbye, hw};
|
|
||||||
UpdateProcThreadAttribute (si_helper.lpAttributeList,
|
|
||||||
0,
|
|
||||||
PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
|
|
||||||
handles_to_inherit,
|
|
||||||
sizeof (handles_to_inherit),
|
|
||||||
NULL, NULL);
|
|
||||||
/* Create helper process */
|
|
||||||
WCHAR cmd[MAX_PATH];
|
|
||||||
path_conv helper ("/bin/cygwin-console-helper.exe");
|
|
||||||
size_t len = helper.get_wide_win32_path_len ();
|
|
||||||
helper.get_wide_win32_path (cmd);
|
|
||||||
__small_swprintf (cmd + len, L" %p %p %p", hello, goodbye, hw);
|
|
||||||
si_helper.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
|
|
||||||
si_helper.StartupInfo.hStdInput = NULL;
|
|
||||||
si_helper.StartupInfo.hStdOutput = NULL;
|
|
||||||
si_helper.StartupInfo.hStdError = NULL;
|
|
||||||
PROCESS_INFORMATION pi_helper;
|
PROCESS_INFORMATION pi_helper;
|
||||||
CreateProcessW (NULL, cmd, &sec_none, &sec_none,
|
|
||||||
TRUE, EXTENDED_STARTUPINFO_PRESENT,
|
|
||||||
NULL, NULL, &si_helper.StartupInfo, &pi_helper);
|
|
||||||
WaitForSingleObject (hello, INFINITE);
|
|
||||||
CloseHandle (hello);
|
|
||||||
CloseHandle (pi_helper.hThread);
|
|
||||||
/* Retrieve pseudo console handles */
|
|
||||||
DWORD rLen;
|
|
||||||
char buf[64];
|
|
||||||
ReadFile (hr, buf, sizeof (buf), &rLen, NULL);
|
|
||||||
buf[rLen] = '\0';
|
|
||||||
HANDLE hpConIn, hpConOut;
|
HANDLE hpConIn, hpConOut;
|
||||||
sscanf (buf, "StdHandles=%p,%p", &hpConIn, &hpConOut);
|
{
|
||||||
DuplicateHandle (pi_helper.hProcess, hpConIn,
|
SIZE_T bytesRequired;
|
||||||
GetCurrentProcess (), &hpConIn, 0,
|
InitializeProcThreadAttributeList (NULL, 2, 0, &bytesRequired);
|
||||||
TRUE, DUPLICATE_SAME_ACCESS);
|
ZeroMemory (&si_helper, sizeof (si_helper));
|
||||||
DuplicateHandle (pi_helper.hProcess, hpConOut,
|
si_helper.StartupInfo.cb = sizeof (STARTUPINFOEXW);
|
||||||
GetCurrentProcess (), &hpConOut, 0,
|
si_helper.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)
|
||||||
TRUE, DUPLICATE_SAME_ACCESS);
|
HeapAlloc (GetProcessHeap (), 0, bytesRequired);
|
||||||
CloseHandle (hr);
|
if (si_helper.lpAttributeList == NULL)
|
||||||
CloseHandle (hw);
|
goto cleanup_pseudo_console;
|
||||||
/* Clean up */
|
if (!InitializeProcThreadAttributeList (si_helper.lpAttributeList,
|
||||||
DeleteProcThreadAttributeList (si_helper.lpAttributeList);
|
2, 0, &bytesRequired))
|
||||||
HeapFree (GetProcessHeap (), 0, si_helper.lpAttributeList);
|
goto cleanup_heap;
|
||||||
|
if (!UpdateProcThreadAttribute (si_helper.lpAttributeList,
|
||||||
|
0,
|
||||||
|
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
|
||||||
|
get_ttyp ()->h_pseudo_console,
|
||||||
|
sizeof (get_ttyp ()->h_pseudo_console),
|
||||||
|
NULL, NULL))
|
||||||
|
goto cleanup_heap;
|
||||||
|
/* Create events for start/stop helper process. */
|
||||||
|
hello = CreateEvent (&sec_none, true, false, NULL);
|
||||||
|
goodbye = CreateEvent (&sec_none, true, false, NULL);
|
||||||
|
/* Create a pipe for receiving pseudo console handles */
|
||||||
|
CreatePipe (&hr, &hw, &sec_none, 0);
|
||||||
|
/* Inherit only handles which are needed by helper. */
|
||||||
|
HANDLE handles_to_inherit[] = {hello, goodbye, hw};
|
||||||
|
if (!UpdateProcThreadAttribute (si_helper.lpAttributeList,
|
||||||
|
0,
|
||||||
|
PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
|
||||||
|
handles_to_inherit,
|
||||||
|
sizeof (handles_to_inherit),
|
||||||
|
NULL, NULL))
|
||||||
|
goto cleanup_event_and_pipes;
|
||||||
|
/* Create helper process */
|
||||||
|
WCHAR cmd[MAX_PATH];
|
||||||
|
path_conv helper ("/bin/cygwin-console-helper.exe");
|
||||||
|
size_t len = helper.get_wide_win32_path_len ();
|
||||||
|
helper.get_wide_win32_path (cmd);
|
||||||
|
__small_swprintf (cmd + len, L" %p %p %p", hello, goodbye, hw);
|
||||||
|
si_helper.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
|
||||||
|
si_helper.StartupInfo.hStdInput = NULL;
|
||||||
|
si_helper.StartupInfo.hStdOutput = NULL;
|
||||||
|
si_helper.StartupInfo.hStdError = NULL;
|
||||||
|
if (!CreateProcessW (NULL, cmd, &sec_none, &sec_none,
|
||||||
|
TRUE, EXTENDED_STARTUPINFO_PRESENT,
|
||||||
|
NULL, NULL, &si_helper.StartupInfo, &pi_helper))
|
||||||
|
goto cleanup_event_and_pipes;
|
||||||
|
WaitForSingleObject (hello, INFINITE);
|
||||||
|
CloseHandle (hello);
|
||||||
|
CloseHandle (pi_helper.hThread);
|
||||||
|
/* Retrieve pseudo console handles */
|
||||||
|
DWORD rLen;
|
||||||
|
char buf[64];
|
||||||
|
if (!ReadFile (hr, buf, sizeof (buf), &rLen, NULL))
|
||||||
|
goto cleanup_helper_process;
|
||||||
|
buf[rLen] = '\0';
|
||||||
|
sscanf (buf, "StdHandles=%p,%p", &hpConIn, &hpConOut);
|
||||||
|
if (!DuplicateHandle (pi_helper.hProcess, hpConIn,
|
||||||
|
GetCurrentProcess (), &hpConIn, 0,
|
||||||
|
TRUE, DUPLICATE_SAME_ACCESS))
|
||||||
|
goto cleanup_helper_process;
|
||||||
|
if (!DuplicateHandle (pi_helper.hProcess, hpConOut,
|
||||||
|
GetCurrentProcess (), &hpConOut, 0,
|
||||||
|
TRUE, DUPLICATE_SAME_ACCESS))
|
||||||
|
goto cleanup_pcon_in;
|
||||||
|
CloseHandle (hr);
|
||||||
|
CloseHandle (hw);
|
||||||
|
/* Clean up */
|
||||||
|
DeleteProcThreadAttributeList (si_helper.lpAttributeList);
|
||||||
|
HeapFree (GetProcessHeap (), 0, si_helper.lpAttributeList);
|
||||||
|
}
|
||||||
/* Setting information of stuffs regarding pseudo console */
|
/* Setting information of stuffs regarding pseudo console */
|
||||||
get_ttyp ()->h_helper_goodbye = goodbye;
|
get_ttyp ()->h_helper_goodbye = goodbye;
|
||||||
get_ttyp ()->h_helper_process = pi_helper.hProcess;
|
get_ttyp ()->h_helper_process = pi_helper.hProcess;
|
||||||
@ -3510,7 +3521,38 @@ fhandler_pty_master::setup_pseudoconsole ()
|
|||||||
CloseHandle (to_master);
|
CloseHandle (to_master);
|
||||||
from_master = hpConIn;
|
from_master = hpConIn;
|
||||||
to_master = hpConOut;
|
to_master = hpConOut;
|
||||||
|
ResizePseudoConsole (get_ttyp ()->h_pseudo_console, size);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
cleanup_pcon_in:
|
||||||
|
CloseHandle (hpConIn);
|
||||||
|
cleanup_helper_process:
|
||||||
|
SetEvent (goodbye);
|
||||||
|
WaitForSingleObject (pi_helper.hProcess, INFINITE);
|
||||||
|
CloseHandle (pi_helper.hProcess);
|
||||||
|
goto skip_close_hello;
|
||||||
|
cleanup_event_and_pipes:
|
||||||
|
CloseHandle (hello);
|
||||||
|
skip_close_hello:
|
||||||
|
CloseHandle (goodbye);
|
||||||
|
CloseHandle (hr);
|
||||||
|
CloseHandle (hw);
|
||||||
|
cleanup_heap:
|
||||||
|
HeapFree (GetProcessHeap (), 0, si_helper.lpAttributeList);
|
||||||
|
cleanup_pseudo_console:
|
||||||
|
{
|
||||||
|
HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console;
|
||||||
|
HANDLE tmp = hp->hConHostProcess;
|
||||||
|
ClosePseudoConsole (get_pseudo_console ());
|
||||||
|
CloseHandle (tmp);
|
||||||
|
}
|
||||||
|
fallback:
|
||||||
|
CloseHandle (from_master);
|
||||||
|
CloseHandle (to_slave);
|
||||||
|
from_master = from_master_cyg;
|
||||||
|
to_slave = NULL;
|
||||||
|
get_ttyp ()->h_pseudo_console = NULL;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -3629,14 +3671,15 @@ fhandler_pty_master::setup ()
|
|||||||
}
|
}
|
||||||
get_ttyp ()->fwd_done = CreateEvent (&sec_none, true, false, NULL);
|
get_ttyp ()->fwd_done = CreateEvent (&sec_none, true, false, NULL);
|
||||||
|
|
||||||
|
t.winsize.ws_col = 80;
|
||||||
|
t.winsize.ws_row = 25;
|
||||||
|
|
||||||
setup_pseudoconsole ();
|
setup_pseudoconsole ();
|
||||||
|
|
||||||
t.set_from_master (from_master);
|
t.set_from_master (from_master);
|
||||||
t.set_from_master_cyg (from_master_cyg);
|
t.set_from_master_cyg (from_master_cyg);
|
||||||
t.set_to_master (to_master);
|
t.set_to_master (to_master);
|
||||||
t.set_to_master_cyg (to_master_cyg);
|
t.set_to_master_cyg (to_master_cyg);
|
||||||
t.winsize.ws_col = 80;
|
|
||||||
t.winsize.ws_row = 25;
|
|
||||||
t.master_pid = myself->pid;
|
t.master_pid = myself->pid;
|
||||||
|
|
||||||
dev ().parse (DEV_PTYM_MAJOR, unit);
|
dev ().parse (DEV_PTYM_MAJOR, unit);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user