From 078713080ee376ba8a490c70c474a1a2d22189c8 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 9 Jul 2012 11:17:55 +0000 Subject: [PATCH] -LRN: Our std handles are not created by us, and thus are inheritable by default. We don't want them to be passed to our child processes, because our parent might be waiting for them to be closed, which would mean that our process is dead. --- src/util/os_priority.c | 58 ++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/src/util/os_priority.c b/src/util/os_priority.c index c9174dee9..ca60f857e 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c @@ -961,6 +961,10 @@ start_process (int pipe_control, long lRet; HANDLE stdin_handle; HANDLE stdout_handle; + BOOL bresult; + DWORD error_code; + HANDLE stdih, stdoh, stdeh; + DWORD stdif, stdof, stdef; if (GNUNET_SYSERR == GNUNET_OS_check_helper_binary (filename)) return NULL; /* not executable */ @@ -1083,8 +1087,7 @@ start_process (int pipe_control, memset (&start, 0, sizeof (start)); start.cb = sizeof (start); - if ((pipe_stdin != NULL) || (pipe_stdout != NULL)) - start.dwFlags |= STARTF_USESTDHANDLES; + start.dwFlags |= STARTF_USESTDHANDLES; if (pipe_stdin != NULL) { @@ -1179,24 +1182,54 @@ start_process (int pipe_control, return NULL; } - if (!CreateProcessW (wpath, wcmd, NULL, NULL, TRUE, - DETACHED_PROCESS | CREATE_SUSPENDED, env_block, NULL, &start, &proc)) + /* Prevents our std handles from being inherited by the child */ + stdih = GetStdHandle (STD_INPUT_HANDLE); + stdoh = GetStdHandle (STD_OUTPUT_HANDLE); + stdeh = GetStdHandle (STD_ERROR_HANDLE); + if (stdih) { - SetErrnoFromWinError (GetLastError ()); + GetHandleInformation (stdih, &stdif); + SetHandleInformation (stdih, HANDLE_FLAG_INHERIT, 0); + } + if (stdoh) + { + GetHandleInformation (stdoh, &stdof); + SetHandleInformation (stdoh, HANDLE_FLAG_INHERIT, 0); + } + if (stdeh) + { + GetHandleInformation (stdeh, &stdef); + SetHandleInformation (stdeh, HANDLE_FLAG_INHERIT, 0); + } + + bresult = CreateProcessW (wpath, wcmd, NULL, NULL, TRUE, + DETACHED_PROCESS | CREATE_SUSPENDED, env_block, NULL, &start, &proc); + error_code = GetLastError (); + + if (stdih) + SetHandleInformation (stdih, stdif, stdif); + if (stdoh) + SetHandleInformation (stdoh, stdof, stdof); + if (stdeh) + SetHandleInformation (stdeh, stdef, stdef); + + GNUNET_free (env_block); + GNUNET_free (cmd); + free (wpath); + free (wcmd); + + if (!bresult) + { + SetErrnoFromWinError (error_code); LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "CreateProcess"); + if (NULL != control_pipe) GNUNET_DISK_file_close (control_pipe); if (NULL != lsocks) GNUNET_DISK_pipe_close (lsocks_pipe); - GNUNET_free (env_block); - GNUNET_free (cmd); - free (wpath); - free (wcmd); return NULL; } - GNUNET_free (env_block); - gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process)); gnunet_proc->pid = proc.dwProcessId; gnunet_proc->handle = proc.hProcess; @@ -1206,9 +1239,6 @@ start_process (int pipe_control, ResumeThread (proc.hThread); CloseHandle (proc.hThread); - GNUNET_free (cmd); - free (wpath); - free (wcmd); if (lsocks == NULL || lsocks[0] == INVALID_SOCKET) return gnunet_proc; -- 2.25.1