Check for sys/resource.h
authorMatthias Clasen <mclasen@redhat.com>
Tue, 16 Oct 2007 05:28:10 +0000 (05:28 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Tue, 16 Oct 2007 05:28:10 +0000 (05:28 +0000)
2007-10-16  Matthias Clasen  <mclasen@redhat.com>

        * configure.in: Check for sys/resource.h

        * glib/gspawn.c: Improve the fdwalk implementation on Linux
        to only walk over actually open file descriptors. (#469231,
        Lennart Poettering)

svn path=/trunk/; revision=5783

ChangeLog
glib/gspawn.c

index 0aa8eb0..ef36062 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-10-16  Matthias Clasen  <mclasen@redhat.com>
+
+       * configure.in: Check for sys/resource.h
+
+       * glib/gspawn.c: Improve the fdwalk implementation on Linux
+       to only walk over actually open file descriptors. (#469231, 
+       Lennart Poettering)
+
 2007-10-13  Sven Herzberg  <herzi@gnome-de.org>
 
        Reviewed by Tim Janik.
index 0420097..c6b249f 100644 (file)
 #include <signal.h>
 #include <string.h>
 #include <stdlib.h>   /* for fdwalk */
+#include <dirent.h>
 
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #endif /* HAVE_SYS_SELECT_H */
 
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
+
 #include "glib.h"
 #include "glibintl.h"
 #include "galias.h"
@@ -884,12 +889,62 @@ fdwalk (int (*cb)(void *data, int fd), void *data)
 {
   gint open_max;
   gint fd;
-  gint res;
+  gint res = 0;
+  
+#ifdef HAVE_SYS_RESOURCE_H
+  struct rlimit rl;
+#endif
+
+#ifdef __linux__  
+  DIR *d;
+
+  if ((d = opendir("/proc/self/fd"))) {
+      struct dirent *de;
+
+      while ((de = readdir(d))) {
+          glong l;
+          gchar *e = NULL;
 
-  res = 0;
-  open_max = sysconf (_SC_OPEN_MAX);
-  for (fd = 0; fd < open_max && res == 0; fd++)
-    res = cb (data, fd);
+          if (de->d_name[0] == '.')
+              continue;
+            
+          errno = 0;
+          l = strtol(de->d_name, &e, 10);
+          if (errno != 0 || !e || *e)
+              continue;
+
+          fd = (gint) l;
+
+          if ((glong) fd != l)
+              continue;
+
+          if (fd == dirfd(d))
+              continue;
+
+          if ((res = cb (data, fd)) != 0)
+              break;
+        }
+      
+      closedir(d);
+      return res;
+  }
+
+  /* If /proc is not mounted or not accessible we fall back to the old
+   * rlimit trick */
+
+#endif
+  
+#ifdef HAVE_SYS_RESOURCE_H
+      
+  if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
+      open_max = rl.rlim_max;
+  else
+#endif
+      open_max = sysconf (_SC_OPEN_MAX);
+
+  for (fd = 0; fd < open_max; fd++)
+      if ((res = cb (data, fd)) != 0)
+          break;
 
   return res;
 }