diff options
author | Antoine Pitrou <pitrou@free.fr> | 2017-07-22 11:22:54 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-22 11:22:54 (GMT) |
commit | 896145d9d266ee2758cfcd7691238cbc1f9e1ab8 (patch) | |
tree | 3b36a7020108c7305a478e174d8a73cdd6deb540 /Lib/test/support | |
parent | 616ecf18f3aacbd8d172e01673877b22fe946e54 (diff) | |
download | cpython-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__.py | 33 |
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 |