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:
Takashi Yano 2020-02-11 02:45:14 +09:00 committed by Corinna Vinschen
parent 9b51beeb2a
commit 8cb20fa5d3
1 changed files with 111 additions and 68 deletions

View File

@ -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,34 +3437,44 @@ 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;
STARTUPINFOEXW si_helper;
HANDLE hello, goodbye;
HANDLE hr, hw;
PROCESS_INFORMATION pi_helper;
HANDLE hpConIn, hpConOut;
{
SIZE_T bytesRequired; SIZE_T bytesRequired;
InitializeProcThreadAttributeList (NULL, 2, 0, &bytesRequired); InitializeProcThreadAttributeList (NULL, 2, 0, &bytesRequired);
STARTUPINFOEXW si_helper;
ZeroMemory (&si_helper, sizeof (si_helper)); ZeroMemory (&si_helper, sizeof (si_helper));
si_helper.StartupInfo.cb = sizeof (STARTUPINFOEXW); si_helper.StartupInfo.cb = sizeof (STARTUPINFOEXW);
si_helper.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST) si_helper.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)
HeapAlloc (GetProcessHeap (), 0, bytesRequired); HeapAlloc (GetProcessHeap (), 0, bytesRequired);
InitializeProcThreadAttributeList (si_helper.lpAttributeList, if (si_helper.lpAttributeList == NULL)
2, 0, &bytesRequired); goto cleanup_pseudo_console;
UpdateProcThreadAttribute (si_helper.lpAttributeList, if (!InitializeProcThreadAttributeList (si_helper.lpAttributeList,
2, 0, &bytesRequired))
goto cleanup_heap;
if (!UpdateProcThreadAttribute (si_helper.lpAttributeList,
0, 0,
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
get_ttyp ()->h_pseudo_console, get_ttyp ()->h_pseudo_console,
sizeof (get_ttyp ()->h_pseudo_console), sizeof (get_ttyp ()->h_pseudo_console),
NULL, NULL); NULL, NULL))
HANDLE hello = CreateEvent (&sec_none, true, false, NULL); goto cleanup_heap;
HANDLE goodbye = CreateEvent (&sec_none, true, false, NULL); /* 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 */ /* Create a pipe for receiving pseudo console handles */
HANDLE hr, hw;
CreatePipe (&hr, &hw, &sec_none, 0); CreatePipe (&hr, &hw, &sec_none, 0);
/* Inherit only handles which are needed by helper. */ /* Inherit only handles which are needed by helper. */
HANDLE handles_to_inherit[] = {hello, goodbye, hw}; HANDLE handles_to_inherit[] = {hello, goodbye, hw};
UpdateProcThreadAttribute (si_helper.lpAttributeList, if (!UpdateProcThreadAttribute (si_helper.lpAttributeList,
0, 0,
PROC_THREAD_ATTRIBUTE_HANDLE_LIST, PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
handles_to_inherit, handles_to_inherit,
sizeof (handles_to_inherit), sizeof (handles_to_inherit),
NULL, NULL); NULL, NULL))
goto cleanup_event_and_pipes;
/* Create helper process */ /* Create helper process */
WCHAR cmd[MAX_PATH]; WCHAR cmd[MAX_PATH];
path_conv helper ("/bin/cygwin-console-helper.exe"); path_conv helper ("/bin/cygwin-console-helper.exe");
@ -3477,31 +3485,34 @@ fhandler_pty_master::setup_pseudoconsole ()
si_helper.StartupInfo.hStdInput = NULL; si_helper.StartupInfo.hStdInput = NULL;
si_helper.StartupInfo.hStdOutput = NULL; si_helper.StartupInfo.hStdOutput = NULL;
si_helper.StartupInfo.hStdError = NULL; si_helper.StartupInfo.hStdError = NULL;
PROCESS_INFORMATION pi_helper; if (!CreateProcessW (NULL, cmd, &sec_none, &sec_none,
CreateProcessW (NULL, cmd, &sec_none, &sec_none,
TRUE, EXTENDED_STARTUPINFO_PRESENT, TRUE, EXTENDED_STARTUPINFO_PRESENT,
NULL, NULL, &si_helper.StartupInfo, &pi_helper); NULL, NULL, &si_helper.StartupInfo, &pi_helper))
goto cleanup_event_and_pipes;
WaitForSingleObject (hello, INFINITE); WaitForSingleObject (hello, INFINITE);
CloseHandle (hello); CloseHandle (hello);
CloseHandle (pi_helper.hThread); CloseHandle (pi_helper.hThread);
/* Retrieve pseudo console handles */ /* Retrieve pseudo console handles */
DWORD rLen; DWORD rLen;
char buf[64]; char buf[64];
ReadFile (hr, buf, sizeof (buf), &rLen, NULL); if (!ReadFile (hr, buf, sizeof (buf), &rLen, NULL))
goto cleanup_helper_process;
buf[rLen] = '\0'; buf[rLen] = '\0';
HANDLE hpConIn, hpConOut;
sscanf (buf, "StdHandles=%p,%p", &hpConIn, &hpConOut); sscanf (buf, "StdHandles=%p,%p", &hpConIn, &hpConOut);
DuplicateHandle (pi_helper.hProcess, hpConIn, if (!DuplicateHandle (pi_helper.hProcess, hpConIn,
GetCurrentProcess (), &hpConIn, 0, GetCurrentProcess (), &hpConIn, 0,
TRUE, DUPLICATE_SAME_ACCESS); TRUE, DUPLICATE_SAME_ACCESS))
DuplicateHandle (pi_helper.hProcess, hpConOut, goto cleanup_helper_process;
if (!DuplicateHandle (pi_helper.hProcess, hpConOut,
GetCurrentProcess (), &hpConOut, 0, GetCurrentProcess (), &hpConOut, 0,
TRUE, DUPLICATE_SAME_ACCESS); TRUE, DUPLICATE_SAME_ACCESS))
goto cleanup_pcon_in;
CloseHandle (hr); CloseHandle (hr);
CloseHandle (hw); CloseHandle (hw);
/* Clean up */ /* Clean up */
DeleteProcThreadAttributeList (si_helper.lpAttributeList); DeleteProcThreadAttributeList (si_helper.lpAttributeList);
HeapFree (GetProcessHeap (), 0, 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);