From: Matthias Clasen Date: Tue, 16 Oct 2007 05:28:10 +0000 (+0000) Subject: Check for sys/resource.h X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=a57cf3893cd0088960dd5d7302f7f7dcd56e4845;p=dana%2Fcg-glib.git Check for sys/resource.h 2007-10-16 Matthias Clasen * 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 --- diff --git a/ChangeLog b/ChangeLog index 0aa8eb0a..ef36062f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-10-16 Matthias Clasen + + * 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 Reviewed by Tim Janik. diff --git a/glib/gspawn.c b/glib/gspawn.c index 0420097a..c6b249f5 100644 --- a/glib/gspawn.c +++ b/glib/gspawn.c @@ -31,11 +31,16 @@ #include #include #include /* for fdwalk */ +#include #ifdef HAVE_SYS_SELECT_H #include #endif /* HAVE_SYS_SELECT_H */ +#ifdef HAVE_SYS_RESOURCE_H +#include +#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; }