[glib/glib-2-62: 4/8] gspawn: Port to g_poll() from select()



commit 8214e07a60ce296e9a7294e8a5d32dcff63b5b98
Author: Philip Withnall <withnall endlessm com>
Date:   Fri Oct 25 16:36:45 2019 +0100

    gspawn: Port to g_poll() from select()
    
    This removes the limitation of select() that only FDs with values lower
    than FD_SETSIZE can be used. Previously, if the out/err pipe FDs had
    high values (which could happen if a large process, like Firefox, was
    spawning subprocesses while having a lot of FDs open), GLib would abort
    due to an assertion failure in libc.
    
    (Minor cherry-pick conflicts when cherry picked to `glib-2-62`. Dropped
    translatable string changes.)
    
    Signed-off-by: Philip Withnall <withnall endlessm com>
    
    Fixes: #954

 glib/gspawn.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)
---
diff --git a/glib/gspawn.c b/glib/gspawn.c
index 3f6d700c1..3acd17375 100644
--- a/glib/gspawn.c
+++ b/glib/gspawn.c
@@ -372,7 +372,6 @@ g_spawn_sync (const gchar          *working_directory,
   gint outpipe = -1;
   gint errpipe = -1;
   GPid pid;
-  fd_set fds;
   gint ret;
   GString *outstr = NULL;
   GString *errstr = NULL;
@@ -435,18 +434,16 @@ g_spawn_sync (const gchar          *working_directory,
          (outpipe >= 0 ||
           errpipe >= 0))
     {
-      ret = 0;
-          
-      FD_ZERO (&fds);
-      if (outpipe >= 0)
-        FD_SET (outpipe, &fds);
-      if (errpipe >= 0)
-        FD_SET (errpipe, &fds);
-          
-      ret = select (MAX (outpipe, errpipe) + 1,
-                    &fds,
-                    NULL, NULL,
-                    NULL /* no timeout */);
+      /* Any negative FD in the array is ignored, so we can use a fixed length.
+       * We can use UNIX FDs here without worrying about Windows HANDLEs because
+       * the Windows implementation is entirely in gspawn-win32.c. */
+      GPollFD fds[] =
+        {
+          { outpipe, G_IO_IN | G_IO_HUP | G_IO_ERR, 0 },
+          { errpipe, G_IO_IN | G_IO_HUP | G_IO_ERR, 0 },
+        };
+
+      ret = g_poll (fds, G_N_ELEMENTS (fds), -1  /* no timeout */);
 
       if (ret < 0)
         {
@@ -466,7 +463,7 @@ g_spawn_sync (const gchar          *working_directory,
           break;
         }
 
-      if (outpipe >= 0 && FD_ISSET (outpipe, &fds))
+      if (outpipe >= 0 && fds[0].revents != 0)
         {
           switch (read_data (outstr, outpipe, error))
             {
@@ -485,7 +482,7 @@ g_spawn_sync (const gchar          *working_directory,
             break;
         }
 
-      if (errpipe >= 0 && FD_ISSET (errpipe, &fds))
+      if (errpipe >= 0 && fds[1].revents != 0)
         {
           switch (read_data (errstr, errpipe, error))
             {


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