-LRN: Our std handles are not created by us, and thus are inheritable by default.
authorChristian Grothoff <christian@grothoff.org>
Mon, 9 Jul 2012 11:17:55 +0000 (11:17 +0000)
committerChristian Grothoff <christian@grothoff.org>
Mon, 9 Jul 2012 11:17:55 +0000 (11:17 +0000)
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

index c9174dee9917155efc363d4ffdccb1d28dad2123..ca60f857e195c82d3b3cbd24f228fcfe0b41063e 100644 (file)
@@ -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;