[glib/glib-2-72: 1/2] glib/win32: fix spawn from GUI regression




commit 44a82bf84cf77f87b70a5108372b7d869bac8aa1
Author: Marc-André Lureau <marcandre lureau redhat com>
Date:   Mon Apr 4 15:46:23 2022 +0400

    glib/win32: fix spawn from GUI regression
    
    In commit 674072b13 ("glib/win32: check if dup() failed in helper
    process"), I happily added checks for dup() calls in the spawn helper.
    However, I didn't realize that GUI applications do not necessarily have
    a console attached, and will now fail spawning processes.
    
    One way to check that is via a _fileno() call, as explained in:
    https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fileno?view=msvc-170#return-value
    
    Fixes:
    https://gitlab.gnome.org/GNOME/glib/-/issues/2628
    
    Signed-off-by: Marc-André Lureau <marcandre lureau redhat com>

 glib/gspawn-win32-helper.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)
---
diff --git a/glib/gspawn-win32-helper.c b/glib/gspawn-win32-helper.c
index 2ca9009a4c..4729ee46ec 100644
--- a/glib/gspawn-win32-helper.c
+++ b/glib/gspawn-win32-helper.c
@@ -292,9 +292,13 @@ main (int ignored_argc, char **ignored_argv)
       checked_dup2 (fd, 1, child_err_report_fd);
     }
 
-  saved_stderr_fd = reopen_noninherited (dup (2), _O_WRONLY);
-  if (saved_stderr_fd == -1)
-    write_err_and_exit (child_err_report_fd, CHILD_DUP_FAILED);
+  /* GUI application do not necessarily have a stderr */
+  if (_fileno (stderr) == 2)
+    {
+      saved_stderr_fd = reopen_noninherited (dup (2), _O_WRONLY);
+      if (saved_stderr_fd == -1)
+        write_err_and_exit (child_err_report_fd, CHILD_DUP_FAILED);
+    }
 
   maxfd = MAX (saved_stderr_fd, maxfd);
   if (argv[ARG_STDERR][0] == '-')
@@ -354,8 +358,11 @@ main (int ignored_argc, char **ignored_argv)
   child_err_report_fd = checked_dup2 (child_err_report_fd, maxfd, child_err_report_fd);
   maxfd++;
   helper_sync_fd = checked_dup2 (helper_sync_fd, maxfd, child_err_report_fd);
-  maxfd++;
-  saved_stderr_fd = checked_dup2 (saved_stderr_fd, maxfd, child_err_report_fd);
+  if (saved_stderr_fd >= 0)
+    {
+      maxfd++;
+      saved_stderr_fd = checked_dup2 (saved_stderr_fd, maxfd, child_err_report_fd);
+    }
 
   {
     GHashTableIter iter;
@@ -381,7 +388,8 @@ main (int ignored_argc, char **ignored_argv)
 
   g_hash_table_add (fds, GINT_TO_POINTER (child_err_report_fd));
   g_hash_table_add (fds, GINT_TO_POINTER (helper_sync_fd));
-  g_hash_table_add (fds, GINT_TO_POINTER (saved_stderr_fd));
+  if (saved_stderr_fd >= 0)
+    g_hash_table_add (fds, GINT_TO_POINTER (saved_stderr_fd));
 
   /* argv[ARG_CLOSE_DESCRIPTORS] is "y" if file descriptors from 3
    *  upwards should be closed
@@ -430,7 +438,9 @@ main (int ignored_argc, char **ignored_argv)
    * Remove redirection so that they would go to original stderr
    * instead of being treated as part of stderr of child process.
    */
-  dup2 (saved_stderr_fd, 2);
+  if (saved_stderr_fd >= 0)
+    dup2 (saved_stderr_fd, 2);
+
   if (handle == -1 && saved_errno != 0)
     {
       int ec = (saved_errno == ENOENT)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]