diff -Nru gpgme1.0-1.6.0/debian/changelog gpgme1.0-1.6.0/debian/changelog --- gpgme1.0-1.6.0/debian/changelog 2015-09-17 07:45:05.000000000 +0000 +++ gpgme1.0-1.6.0/debian/changelog 2018-03-20 14:08:42.000000000 +0000 @@ -1,3 +1,9 @@ +gpgme1.0 (1.6.0-1ppa1) xenial; urgency=medium + + * Backport get_max_fds optimization on Linux from 1.10.0. + + -- Colin Watson Tue, 20 Mar 2018 14:08:33 +0000 + gpgme1.0 (1.6.0-1) unstable; urgency=medium * New upstream release. diff -Nru gpgme1.0-1.6.0/debian/patches/0002-optimize-get_max_fds-on-linux.patch gpgme1.0-1.6.0/debian/patches/0002-optimize-get_max_fds-on-linux.patch --- gpgme1.0-1.6.0/debian/patches/0002-optimize-get_max_fds-on-linux.patch 1970-01-01 00:00:00.000000000 +0000 +++ gpgme1.0-1.6.0/debian/patches/0002-optimize-get_max_fds-on-linux.patch 2018-03-20 14:28:50.000000000 +0000 @@ -0,0 +1,175 @@ +Description: Optimize get_max_fds on Linux + * src/posix-io.c (get_max_fds): Restore Linux optimization, this time + using open/getdents/close rather than opendir/readdir/closedir. + . + opendir/readdir/closedir may allocate/free memory, and aren't required + to do so in an async-signal-safe way. On the other hand, opening + /proc/self/fd directly and iterating over it using getdents is safe. + . + (getdents is not strictly speaking documented to be async-signal-safe + because it's not in POSIX. However, the Linux implementation is + essentially just a souped-up read. Python >= 3.2.3 makes the same + assumption.) +Author: Werner Koch +Author: Colin Watson +Author: Daniel Kahn Gillmor +Origin: backport, https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gpgme.git;a=commitdiff;h=89d22f9229f2ecd559ac6ea91dae60eeff940fa5 +Origin: backport, https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gpgme.git;a=commitdiff;h=b5b996b1a142abb90296f5feadf0b5b19c59f738 +Origin: upstream, https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gpgme.git;a=commitdiff;h=4632adf403611b50be2b4e852a4607070935d0e5 +Origin: upstream, https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gpgme.git;a=commitdiff;h=00daac15530eabed5e61d841b2df939c2242667c +Last-Update: 2018-03-20 + +Index: b/configure.ac +=================================================================== +--- a/configure.ac ++++ b/configure.ac +@@ -529,7 +529,28 @@ + AM_CONDITIONAL(HAVE_UISERVER, test "$uiserver" != "no") + + ++# Option --disable-linux-getdents ++# ++# By default we use SYS_getdents on Linux to optimize fd closing ++# before an exec. This option allows to switch this optimization off. ++use_linux_getdents=yes ++AC_ARG_ENABLE(linux-getdents, ++ AC_HELP_STRING([--disable-linux-getdents], ++ [do not use SYS_getdents on Linux]), ++ use_linux_getdents=$enableval) ++if test "$use_linux_getdents" = "yes"; then ++ case "${host}" in ++ *-*-linux*) ++ AC_DEFINE(USE_LINUX_GETDENTS,1, ++ [Defined if SYS_getdents can be used on Linux]) ++ ;; ++ esac ++fi ++ ++ ++# + # Add a few constants to help porting to W32 ++# + AH_VERBATIM([SEPCONSTANTS], + [ + /* Separators as used in $PATH and file name. */ +Index: b/src/posix-io.c +=================================================================== +--- a/src/posix-io.c ++++ b/src/posix-io.c +@@ -44,6 +44,12 @@ + #include + #include + ++#ifdef USE_LINUX_GETDENTS ++# include ++# include ++# include ++#endif /*USE_LINUX_GETDENTS*/ ++ + #include "util.h" + #include "priv-io.h" + #include "sema.h" +@@ -270,6 +276,21 @@ + } + + ++#ifdef USE_LINUX_GETDENTS ++/* This is not declared in public headers; getdents64(2) says that we must ++ * define it ourselves. */ ++struct linux_dirent64 ++{ ++ ino64_t d_ino; ++ off64_t d_off; ++ unsigned short d_reclen; ++ unsigned char d_type; ++ char d_name[]; ++}; ++ ++# define DIR_BUF_SIZE 1024 ++#endif /*USE_LINUX_GETDENTS*/ ++ + static long int + get_max_fds (void) + { +@@ -277,16 +298,74 @@ + long int fds = -1; + int rc; + +-#ifdef RLIMIT_NOFILE ++ /* Under Linux we can figure out the highest used file descriptor by ++ * reading /proc/self/fd. This is in the common cases much faster ++ * than for example doing 4096 close calls where almost all of them ++ * will fail. ++ * ++ * We can't use the normal opendir/readdir/closedir interface between ++ * fork and exec in a multi-threaded process because opendir uses ++ * malloc and thus a mutex which may deadlock with a malloc in another ++ * thread. However, the underlying getdents system call is safe. */ ++#ifdef USE_LINUX_GETDENTS + { +- struct rlimit rl; +- rc = getrlimit (RLIMIT_NOFILE, &rl); +- if (rc == 0) ++ int dir_fd; ++ char dir_buf[DIR_BUF_SIZE]; ++ struct linux_dirent64 *dir_entry; ++ int r, pos; ++ const char *s; ++ int x; ++ ++ dir_fd = open ("/proc/self/fd", O_RDONLY | O_DIRECTORY); ++ if (dir_fd != -1) ++ { ++ for (;;) ++ { ++ r = syscall(SYS_getdents64, dir_fd, dir_buf, DIR_BUF_SIZE); ++ if (r == -1) ++ { ++ /* Fall back to other methods. */ ++ fds = -1; ++ break; ++ } ++ if (r == 0) ++ break; ++ ++ for (pos = 0; pos < r; pos += dir_entry->d_reclen) ++ { ++ dir_entry = (struct linux_dirent64 *) (dir_buf + pos); ++ s = dir_entry->d_name; ++ if (*s < '0' || *s > '9') ++ continue; ++ /* atoi is not guaranteed to be async-signal-safe. */ ++ for (x = 0; *s >= '0' && *s <= '9'; s++) ++ x = x * 10 + (*s - '0'); ++ if (!*s && x > fds && x != dir_fd) ++ fds = x; ++ } ++ } ++ ++ close (dir_fd); ++ } ++ if (fds != -1) + { +- source = "RLIMIT_NOFILE"; +- fds = rl.rlim_max; ++ fds++; ++ source = "/proc"; + } +- } ++ } ++#endif /*USE_LINUX_GETDENTS*/ ++ ++#ifdef RLIMIT_NOFILE ++ if (fds == -1) ++ { ++ struct rlimit rl; ++ rc = getrlimit (RLIMIT_NOFILE, &rl); ++ if (rc == 0) ++ { ++ source = "RLIMIT_NOFILE"; ++ fds = rl.rlim_max; ++ } ++ } + #endif + #ifdef RLIMIT_OFILE + if (fds == -1) diff -Nru gpgme1.0-1.6.0/debian/patches/series gpgme1.0-1.6.0/debian/patches/series --- gpgme1.0-1.6.0/debian/patches/series 2015-09-17 07:50:19.000000000 +0000 +++ gpgme1.0-1.6.0/debian/patches/series 2018-03-20 13:56:55.000000000 +0000 @@ -1 +1,2 @@ 0001-avoid-identifying-as-beta.patch +0002-optimize-get_max_fds-on-linux.patch