[Pkg-gnupg-commit] [gnupg2] 34/102: common: Speedup closing fds before an exec.

Daniel Kahn Gillmor dkg at fifthhorseman.net
Fri Jun 17 00:14:51 UTC 2016


This is an automated email from the git hooks/post-receive script.

dkg pushed a commit to branch experimental
in repository gnupg2.

commit 512c56af43027149e8beacf259746b8d7bf9b1a2
Author: Werner Koch <wk at gnupg.org>
Date:   Fri May 27 22:02:54 2016 +0200

    common: Speedup closing fds before an exec.
    
    * common/exechelp-posix.c [__linux__]: Include dirent.h.
    (get_max_fds) [__linux__]: Return the actual used highest fd.
    --
    
    Signed-off-by: Werner Koch <wk at gnupg.org>
---
 common/exechelp-posix.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c
index 87c6e55..81831ee 100644
--- a/common/exechelp-posix.c
+++ b/common/exechelp-posix.c
@@ -67,6 +67,11 @@
 # include <sys/stat.h>
 #endif
 
+#if __linux__
+# include <sys/types.h>
+# include <dirent.h>
+#endif /*__linux__ */
+
 #include "util.h"
 #include "i18n.h"
 #include "sysutils.h"
@@ -97,6 +102,45 @@ get_max_fds (void)
 #ifdef HAVE_GETRLIMIT
   struct rlimit rl;
 
+  /* Under Linux we can figure out the highest used file descriptor by
+   * reading /proc/PID/fd.  This is in the common cases much fast than
+   * for example doing 4096 close calls where almost all of them will
+   * fail.  On a system with a limit of 4096 files and only 8 files
+   * open with the highest number being 10, we speedup close_all_fds
+   * from 125ms to 0.4ms including readdir.
+   *
+   * Another option would be to close the file descriptors as returned
+   * from reading that directory - however then we need to snapshot
+   * that list before starting to close them.  */
+#ifdef __linux__
+  {
+    char dirname[50];
+    DIR *dir = NULL;
+    struct dirent *dir_entry;
+    const char *s;
+    int x;
+
+    snprintf (dirname, sizeof dirname, "/proc/%u/fd", (unsigned int)getpid ());
+    dir = opendir (dirname);
+    if (dir)
+      {
+        while ((dir_entry = readdir (dir)))
+          {
+            s = dir_entry->d_name;
+            if ( *s < '0' || *s > '9')
+              continue;
+            x = atoi (s);
+            if (x > max_fds)
+              max_fds = x;
+          }
+        closedir (dir);
+      }
+    if (max_fds != -1)
+      return max_fds + 1;
+    }
+#endif /* __linux__ */
+
+
 # ifdef RLIMIT_NOFILE
   if (!getrlimit (RLIMIT_NOFILE, &rl))
     max_fds = rl.rlim_max;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git



More information about the Pkg-gnupg-commit mailing list