diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index aa26ec4..cbbbd26 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -8680,13 +8680,19 @@ 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 HAVE_CLOSE_RANGE +#define USE_CLOSE_RANGE +#else #ifdef __FreeBSD__ #define USE_CLOSEFROM #endif /* __FreeBSD__ */ @@ -8694,6 +8700,7 @@ os_close_impl(PyObject *module, int fd) #ifdef HAVE_FDWALK #define USE_FDWALK #endif /* HAVE_FDWALK */ +#endif /* HAVE_CLOSE_RANGE */ #ifdef USE_FDWALK static int @@ -8722,6 +8729,10 @@ _Py_closerange(int first, int last) #endif first = Py_MAX(first, 0); +#ifdef USE_CLOSE_RANGE +#error yes + close_range(first, last, 0); +#else #ifdef USE_CLOSEFROM if (last >= sysconf(_SC_OPEN_MAX)) { /* Any errors encountered while closing file descriptors are ignored */ @@ -8743,6 +8754,7 @@ _Py_closerange(int first, int last) } } #endif /* USE_FDWALK */ +#endif /* USE_CLOSE_RANGE */ } /*[clinic input] diff --git a/configure b/configure index 29d5f4c..6272717 100755 --- a/configure +++ b/configure @@ -11601,8 +11601,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 240ddeb..4a5ecf4 100644 --- a/configure.ac +++ b/configure.ac @@ -3616,8 +3616,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 76a1047..32b8cdb 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -136,6 +136,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