Browse Source

Promptly close pipe handles passed to child

Parent keeping the handle to write end of child's stdout will
cause ERROR_BROKEN_PIPE not signalled if/when the child exits.

Also add a wrapper for CloseHandle()

Fixes the GUI process hanging in read from child
if the latter unexpectedly dies due to some error.
Trac #1203

Signed-off-by: Selva Nair <selva.nair@gmail.com>
pull/312/head
Selva Nair 5 years ago committed by Gert Doering
parent
commit
5ab2a48ba0
  1. 10
      misc.c
  2. 2
      misc.h
  3. 27
      openvpn.c

10
misc.c

@ -499,3 +499,13 @@ wcs_concat2(WCHAR *dest, int len, const WCHAR *src1, const WCHAR *src2, const WC
n = 0;
dest[n] = L'\0';
}
void
CloseHandleEx(LPHANDLE handle)
{
if (handle && *handle && *handle != INVALID_HANDLE_VALUE)
{
CloseHandle(*handle);
*handle = INVALID_HANDLE_VALUE;
}
}

2
misc.h

@ -44,5 +44,7 @@ BOOL validate_input(const WCHAR *input, const WCHAR *exclude);
/* Concatenate two wide strings with a separator */
void wcs_concat2(WCHAR *dest, int len, const WCHAR *src1, const WCHAR *src2, const WCHAR *sep);
void CloseSemaphore(HANDLE sem);
/* Close a handle if not null or invalid */
void CloseHandleEx(LPHANDLE h);
#endif

27
openvpn.c

@ -2022,6 +2022,9 @@ StartOpenVPN(connection_t *c)
goto out;
}
CloseHandleEx(&hStdInRead);
CloseHandleEx(&hNul);
/* Pass management password to OpenVPN process */
c->manage.password[sizeof(c->manage.password) - 1] = '\n';
WriteFile(hStdInWrite, c->manage.password, sizeof(c->manage.password), &written, NULL);
@ -2159,8 +2162,8 @@ ReadLineFromStdOut(HANDLE hStdOut, char *line, DWORD size)
BOOL
CheckVersion()
{
HANDLE hStdOutRead;
HANDLE hStdOutWrite;
HANDLE hStdOutRead = NULL;
HANDLE hStdOutWrite = NULL;
BOOL retval = FALSE;
STARTUPINFO si;
PROCESS_INFORMATION pi;
@ -2217,19 +2220,23 @@ CheckVersion()
si.hStdError = hStdOutWrite;
/* Start OpenVPN to check version */
if (!CreateProcess(o.exe_path, cmdline, NULL, NULL, TRUE,
CREATE_NO_WINDOW, NULL, pwd, &si, &pi))
bool success = CreateProcess(o.exe_path, cmdline, NULL, NULL, TRUE,
CREATE_NO_WINDOW, NULL, pwd, &si, &pi);
if (!success)
{
ShowLocalizedMsg(IDS_ERR_CREATE_PROCESS, o.exe_path, cmdline, pwd);
goto out;
}
else if (ReadLineFromStdOut(hStdOutRead, line, sizeof(line)))
CloseHandleEx(&hStdOutWrite);
CloseHandleEx(&pi.hThread);
CloseHandleEx(&pi.hProcess);
if (ReadLineFromStdOut(hStdOutRead, line, sizeof(line)))
{
#ifdef DEBUG
PrintDebug(_T("VersionString: %S"), line);
#endif
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
/* OpenVPN version 2.x */
char *p = strstr(line, match_version);
if (p)
@ -2242,8 +2249,8 @@ CheckVersion()
}
out:
CloseHandle(hStdOutRead);
CloseHandle(hStdOutWrite);
CloseHandleEx(&hStdOutWrite);
CloseHandleEx(&hStdOutRead);
return retval;
}

Loading…
Cancel
Save