summaryrefslogtreecommitdiffstats
path: root/Lib/test/support
diff options
context:
space:
mode:
authorAntoine Pitrou <pitrou@free.fr>2017-07-22 11:22:54 (GMT)
committerGitHub <noreply@github.com>2017-07-22 11:22:54 (GMT)
commit896145d9d266ee2758cfcd7691238cbc1f9e1ab8 (patch)
tree3b36a7020108c7305a478e174d8a73cdd6deb540 /Lib/test/support
parent616ecf18f3aacbd8d172e01673877b22fe946e54 (diff)
downloadcpython-896145d9d266ee2758cfcd7691238cbc1f9e1ab8.zip
cpython-896145d9d266ee2758cfcd7691238cbc1f9e1ab8.tar.gz
cpython-896145d9d266ee2758cfcd7691238cbc1f9e1ab8.tar.bz2
bpo-26732: fix too many fds in processes started with the "forkserver" method (#2813)
* bpo-26732: fix too many fds in processes started with the "forkserver" method A child process would inherit as many fds as the number of still-running children. * Add blurb and test comment
Diffstat (limited to 'Lib/test/support')
-rw-r--r--Lib/test/support/__init__.py33
1 files changed, 32 insertions, 1 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 313c230..3a4d27e 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -107,7 +107,7 @@ __all__ = [
"check_warnings", "check_no_resource_warning", "EnvironmentVarGuard",
"run_with_locale", "swap_item",
"swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict",
- "run_with_tz", "PGO", "missing_compiler_executable",
+ "run_with_tz", "PGO", "missing_compiler_executable", "fd_count",
]
class Error(Exception):
@@ -2647,3 +2647,34 @@ def disable_faulthandler():
finally:
if is_enabled:
faulthandler.enable(file=fd, all_threads=True)
+
+
+try:
+ MAXFD = os.sysconf("SC_OPEN_MAX")
+except Exception:
+ MAXFD = 256
+
+
+def fd_count():
+ """Count the number of open file descriptors.
+ """
+ if sys.platform.startswith(('linux', 'freebsd')):
+ try:
+ names = os.listdir("/proc/self/fd")
+ return len(names)
+ except FileNotFoundError:
+ pass
+
+ count = 0
+ for fd in range(MAXFD):
+ try:
+ # Prefer dup() over fstat(). fstat() can require input/output
+ # whereas dup() doesn't.
+ fd2 = os.dup(fd)
+ except OSError as e:
+ if e.errno != errno.EBADF:
+ raise
+ else:
+ os.close(fd2)
+ count += 1
+ return count