+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.
#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"
{
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;
}