[glib: 6/7] glib/win32: fix passing same fd for stdout & stderr spawn




commit e05227371dbd35300e13328e9c0ce275b88108a5
Author: Marc-André Lureau <marcandre lureau redhat com>
Date:   Fri Feb 4 12:30:10 2022 +0400

    glib/win32: fix passing same fd for stdout & stderr spawn
    
    Delay closing the FDs after all input FDs are duped.
    
    Signed-off-by: Marc-André Lureau <marcandre lureau redhat com>

 glib/gspawn-win32-helper.c      | 27 ++++++++++++---------------
 glib/gspawn.c                   |  4 ----
 glib/tests/spawn-singlethread.c |  2 --
 3 files changed, 12 insertions(+), 21 deletions(-)
---
diff --git a/glib/gspawn-win32-helper.c b/glib/gspawn-win32-helper.c
index 58fd719fa..2ca9009a4 100644
--- a/glib/gspawn-win32-helper.c
+++ b/glib/gspawn-win32-helper.c
@@ -154,7 +154,7 @@ protect_wargv (gint       argc,
 }
 
 static int
-checked_dup2 (int oldfd, int newfd, int report_fd, gboolean close_old)
+checked_dup2 (int oldfd, int newfd, int report_fd)
 {
   if (oldfd == newfd)
     return newfd;
@@ -162,9 +162,6 @@ checked_dup2 (int oldfd, int newfd, int report_fd, gboolean close_old)
   if (dup2 (oldfd, newfd) == -1)
     write_err_and_exit (report_fd, CHILD_DUP_FAILED);
 
-  if (close_old)
-    close (oldfd);
-
   return newfd;
 }
 
@@ -274,12 +271,12 @@ main (int ignored_argc, char **ignored_argv)
   else if (argv[ARG_STDIN][0] == 'z')
     {
       fd = open ("NUL:", O_RDONLY);
-      checked_dup2 (fd, 0, child_err_report_fd, TRUE);
+      checked_dup2 (fd, 0, child_err_report_fd);
     }
   else
     {
       fd = atoi (argv[ARG_STDIN]);
-      checked_dup2 (fd, 0, child_err_report_fd, TRUE);
+      checked_dup2 (fd, 0, child_err_report_fd);
     }
 
   if (argv[ARG_STDOUT][0] == '-')
@@ -287,12 +284,12 @@ main (int ignored_argc, char **ignored_argv)
   else if (argv[ARG_STDOUT][0] == 'z')
     {
       fd = open ("NUL:", O_WRONLY);
-      checked_dup2 (fd, 1, child_err_report_fd, TRUE);
+      checked_dup2 (fd, 1, child_err_report_fd);
     }
   else
     {
       fd = atoi (argv[ARG_STDOUT]);
-      checked_dup2 (fd, 1, child_err_report_fd, TRUE);
+      checked_dup2 (fd, 1, child_err_report_fd);
     }
 
   saved_stderr_fd = reopen_noninherited (dup (2), _O_WRONLY);
@@ -305,12 +302,12 @@ main (int ignored_argc, char **ignored_argv)
   else if (argv[ARG_STDERR][0] == 'z')
     {
       fd = open ("NUL:", O_WRONLY);
-      checked_dup2 (fd, 2, child_err_report_fd, TRUE);
+      checked_dup2 (fd, 2, child_err_report_fd);
     }
   else
     {
       fd = atoi (argv[ARG_STDERR]);
-      checked_dup2 (fd, 2, child_err_report_fd, TRUE);
+      checked_dup2 (fd, 2, child_err_report_fd);
     }
 
   /* argv[ARG_WORKING_DIRECTORY] is the directory in which to run the
@@ -354,11 +351,11 @@ main (int ignored_argc, char **ignored_argv)
     }
 
   maxfd++;
-  child_err_report_fd = checked_dup2 (child_err_report_fd, maxfd, child_err_report_fd, TRUE);
+  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, TRUE);
+  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, TRUE);
+  saved_stderr_fd = checked_dup2 (saved_stderr_fd, maxfd, child_err_report_fd);
 
   {
     GHashTableIter iter;
@@ -373,13 +370,13 @@ main (int ignored_argc, char **ignored_argv)
          * fds are larger than any target fd to avoid introducing new conflicts.
          */
         maxfd++;
-        checked_dup2 (GPOINTER_TO_INT (sourcefd), maxfd, child_err_report_fd, TRUE);
+        checked_dup2 (GPOINTER_TO_INT (sourcefd), maxfd, child_err_report_fd);
         g_hash_table_iter_replace (&iter, GINT_TO_POINTER (maxfd));
       }
 
     g_hash_table_iter_init (&iter, fds);
     while (g_hash_table_iter_next (&iter, &targetfd, &sourcefd))
-      checked_dup2 (GPOINTER_TO_INT (sourcefd), GPOINTER_TO_INT (targetfd), child_err_report_fd, TRUE);
+      checked_dup2 (GPOINTER_TO_INT (sourcefd), GPOINTER_TO_INT (targetfd), child_err_report_fd);
   }
 
   g_hash_table_add (fds, GINT_TO_POINTER (child_err_report_fd));
diff --git a/glib/gspawn.c b/glib/gspawn.c
index 60da07198..1128221cc 100644
--- a/glib/gspawn.c
+++ b/glib/gspawn.c
@@ -856,8 +856,6 @@ g_spawn_async_with_pipes (const gchar          *working_directory,
  * windows on the right screen, you may want to use #GdkAppLaunchContext,
  * #GAppLaunchContext, or set the `DISPLAY` environment variable.
  *
- * On Windows, sharing the same FD for @stdout_fd and @stderr_fd is not supported.
- *
  * Returns: %TRUE on success, %FALSE if an error was set
  *
  * Since: 2.68
@@ -940,8 +938,6 @@ g_spawn_async_with_pipes_and_fds (const gchar           *working_directory,
  * Identical to g_spawn_async_with_pipes_and_fds() but with `n_fds` set to zero,
  * so no FD assignments are used.
  *
- * On Windows, sharing the same FD for @stdout_fd and @stderr_fd is not supported.
- *
  * Returns: %TRUE on success, %FALSE if an error was set
  *
  * Since: 2.58
diff --git a/glib/tests/spawn-singlethread.c b/glib/tests/spawn-singlethread.c
index 159e8c34a..7711ba8fe 100644
--- a/glib/tests/spawn-singlethread.c
+++ b/glib/tests/spawn-singlethread.c
@@ -196,9 +196,7 @@ test_spawn_async_with_fds (void)
     { NO_FD, NO_FD, NO_FD },       /* Test with no fds passed */
     { NO_FD, FD_NEGATIVE, NO_FD }, /* Test another negative fd value */
     { PIPE, PIPE, PIPE },          /* Test with unique fds passed */
-#ifndef G_OS_WIN32
     { NO_FD, PIPE, STDOUT_PIPE },  /* Test the same fd for stdout + stderr */
-#endif
   };
 
   arg = g_strdup_printf ("thread %d", tnum);


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