[glib: 2/5] gspawn: Use fdwalk provided by system only when it is known to be safe



commit 8af823c8e5f5c164a3b0e5ac3ccdafd647c1ba2b
Author: Ting-Wei Lan <lantw src gnome org>
Date:   Fri Sep 20 22:36:30 2019 +0800

    gspawn: Use fdwalk provided by system only when it is known to be safe
    
    All uses of fdwalk in gspawn are between fork and exec, which means only
    async-signal safe functions can be called if the parent process has
    multiple threads. Since fdwalk is not a standard API, we should not
    assume it is safe to use unless the manual of the system explicitly says
    it is async-signal safe.
    
    Fixes: #1638

 glib/gspawn.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)
---
diff --git a/glib/gspawn.c b/glib/gspawn.c
index ea5e15034..f17559a48 100644
--- a/glib/gspawn.c
+++ b/glib/gspawn.c
@@ -1148,7 +1148,6 @@ close_func (void *data, int fd)
   return 0;
 }
 
-#ifndef HAVE_FDWALK
 #ifdef __linux__
 struct linux_dirent64
 {
@@ -1188,8 +1187,21 @@ filename_to_fd (const char *p)
 #endif
 
 static int
-fdwalk (int (*cb)(void *data, int fd), void *data)
+safe_fdwalk (int (*cb)(void *data, int fd), void *data)
 {
+#if 0
+  /* Use fdwalk function provided by the system if it is known to be
+   * async-signal safe.
+   *
+   * Currently there are no operating systems known to provide a safe
+   * implementation, so this section is not used for now.
+   */
+  return fdwalk (cb, data);
+#else
+  /* Fallback implementation of fdwalk. It should be async-signal safe, but it
+   * may be slow on non-Linux operating systems, especially on systems allowing
+   * very high number of open file descriptors.
+   */
   gint open_max;
   gint fd;
   gint res = 0;
@@ -1244,8 +1256,8 @@ fdwalk (int (*cb)(void *data, int fd), void *data)
           break;
 
   return res;
+#endif
 }
-#endif /* HAVE_FDWALK */
 
 static void
 safe_closefrom (int lowfd)
@@ -1275,7 +1287,7 @@ safe_closefrom (int lowfd)
    */
   (void) fcntl (lowfd, F_CLOSEM);
 #else
-  (void) fdwalk (close_func, GINT_TO_POINTER (lowfd));
+  (void) safe_fdwalk (close_func, GINT_TO_POINTER (lowfd));
 #endif
 }
 
@@ -1407,7 +1419,7 @@ do_exec (gint                  child_err_report_fd,
         }
       else
         {
-          fdwalk (set_cloexec, GINT_TO_POINTER (3));
+          safe_fdwalk (set_cloexec, GINT_TO_POINTER (3));
         }
     }
   else


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