From a2b6c30e825eacbd39a1094ec94eb320e8087792 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Mon, 27 Apr 2020 18:05:05 -0500 Subject: [PATCH 1/4] configure: start checking for close_range --- configure | 4 ++-- configure.ac | 4 ++-- pyconfig.h.in | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/configure b/configure index ad74754e9a7215..89577d85a41482 100755 --- a/configure +++ b/configure @@ -11672,8 +11672,8 @@ fi # checks for library functions for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ - clock confstr copy_file_range ctermid dup3 execv explicit_bzero explicit_memset \ - faccessat fchmod fchmodat fchown fchownat \ + clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \ + explicit_memset faccessat fchmod fchmodat fchown fchownat \ fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ futimens futimes gai_strerror getentropy \ getgrgid_r getgrnam_r \ diff --git a/configure.ac b/configure.ac index f0bc8c625844b6..3ec274c576edfd 100644 --- a/configure.ac +++ b/configure.ac @@ -3664,8 +3664,8 @@ fi # checks for library functions AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ - clock confstr copy_file_range ctermid dup3 execv explicit_bzero explicit_memset \ - faccessat fchmod fchmodat fchown fchownat \ + clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \ + explicit_memset faccessat fchmod fchmodat fchown fchownat \ fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ futimens futimes gai_strerror getentropy \ getgrgid_r getgrnam_r \ diff --git a/pyconfig.h.in b/pyconfig.h.in index c162a3c33e57b6..298cb4fa12f80c 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -139,6 +139,9 @@ /* Define to 1 if you have the `clock_settime' function. */ #undef HAVE_CLOCK_SETTIME +/* Define to 1 if you have the `close_range' function. */ +#undef HAVE_CLOSE_RANGE + /* Define if the C compiler supports computed gotos. */ #undef HAVE_COMPUTED_GOTOS From fd8a00870ce0c8a8574eb640bbd62a1e043ba312 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Tue, 28 Apr 2020 08:14:03 -0500 Subject: [PATCH 2/4] _Py_closerange: add close_range(2) support --- Modules/posixmodule.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 321eaec63c4a48..701e9eb845403e 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -8741,12 +8741,15 @@ os_close_impl(PyObject *module, int fd) } /* Our selection logic for which function to use is as follows: - * 1. If closefrom(2) is available, we'll attempt to use that next if we're + * 1. If close_range(2) is available, always prefer that; it's better for + * contiguous ranges like this than fdwalk(3) which entails iterating over + * the entire fd space and simply doing nothing for those outside the range. + * 2. If closefrom(2) is available, we'll attempt to use that next if we're * closing up to sysconf(_SC_OPEN_MAX). - * 1a. Fallback to fdwalk(3) if we're not closing up to sysconf(_SC_OPEN_MAX), + * 2a. Fallback to fdwalk(3) if we're not closing up to sysconf(_SC_OPEN_MAX), * as that will be more performant if the range happens to have any chunk of * non-opened fd in the middle. - * 1b. If fdwalk(3) isn't available, just do a plain close(2) loop. + * 2b. If fdwalk(3) isn't available, just do a plain close(2) loop. */ #ifdef __FreeBSD__ #define USE_CLOSEFROM @@ -8779,6 +8782,14 @@ void _Py_closerange(int first, int last) { first = Py_MAX(first, 0); +#ifdef HAVE_CLOSE_RANGE + if (close_range(first, last, 0) == -1 && errno != ENOSYS) { + /* Any errors encountered while closing file descriptors are ignored; + * ENOSYS means no kernel support, though, + * so we'll fallback to the other methods. */ + } + else +#endif /* HAVE_CLOSE_RANGE */ #ifdef USE_CLOSEFROM if (last >= sysconf(_SC_OPEN_MAX)) { /* Any errors encountered while closing file descriptors are ignored */ From 3081c11b411bb64c25a80bc6244bd056a9d027f2 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sun, 11 Oct 2020 19:17:45 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/C API/2020-10-11-19-17-44.bpo-40423.GsmgEj.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/C API/2020-10-11-19-17-44.bpo-40423.GsmgEj.rst diff --git a/Misc/NEWS.d/next/C API/2020-10-11-19-17-44.bpo-40423.GsmgEj.rst b/Misc/NEWS.d/next/C API/2020-10-11-19-17-44.bpo-40423.GsmgEj.rst new file mode 100644 index 00000000000000..44e571ebf86daf --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-10-11-19-17-44.bpo-40423.GsmgEj.rst @@ -0,0 +1,3 @@ +The :mod:`subprocess` module and ``os.closerange`` will now use the +``close_range(low, high, flags)`` syscall when it is available for more +efficient closing of ranges of descriptors. \ No newline at end of file From e1dc81975c036b622384e33ae4df0f41eb1bf193 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 11 Oct 2020 14:37:40 -0500 Subject: [PATCH 4/4] _Py_closerange: last-minute braino, flip logic around --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 701e9eb845403e..2e0caaa3e561ba 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -8783,7 +8783,7 @@ _Py_closerange(int first, int last) { first = Py_MAX(first, 0); #ifdef HAVE_CLOSE_RANGE - if (close_range(first, last, 0) == -1 && errno != ENOSYS) { + if (close_range(first, last, 0) == 0 || errno != ENOSYS) { /* Any errors encountered while closing file descriptors are ignored; * ENOSYS means no kernel support, though, * so we'll fallback to the other methods. */