From: Sami Kerola Date: Sat, 14 Nov 2020 12:55:10 +0000 (+0000) Subject: login: use close_range() system call when possible X-Git-Tag: v2.37-rc1~246 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f0649c0d83f30c7e2318ba0f578a55d875cca4d7;p=thirdparty%2Futil-linux.git login: use close_range() system call when possible This system call was added while back, but does not have glibc support yet. Lets try to use the new facility early on. The promise in reference link is that the new call is faster, and works when /proc is not mounted. Reference: https://lwn.net/Articles/789000/ Reference: https://lwn.net/Articles/789023/ Reference: https://kernelnewbies.org/LinuxChanges#Linux_5.9.New_close_range.28.29_system_call_for_easier_closing_of_file_descriptors Signed-off-by: Sami Kerola --- diff --git a/configure.ac b/configure.ac index 8f026c85a0..a2ac7a6da4 100644 --- a/configure.ac +++ b/configure.ac @@ -497,6 +497,7 @@ AC_CHECK_DECL([SO_PASSCRED], AC_CHECK_FUNCS([ \ clearenv \ + close_range \ __fpurge \ fpurge \ __fpending \ @@ -571,6 +572,7 @@ AS_IF([test "x$ul_cv_syscall_setns" = xno], [ UL_CHECK_SYSCALL([pidfd_open]) UL_CHECK_SYSCALL([pidfd_send_signal]) +UL_CHECK_SYSCALL([close_range]) AC_CHECK_FUNCS([isnan], [], [AC_CHECK_LIB([m], [isnan], [MATH_LIBS="-lm"])] diff --git a/include/fileutils.h b/include/fileutils.h index 618bf39967..1de214bcad 100644 --- a/include/fileutils.h +++ b/include/fileutils.h @@ -72,6 +72,20 @@ static inline struct dirent *xreaddir(DIR *dp) return d; } +#if defined(__linux__) +# include +# if defined(SYS_close_range) +# include +# ifndef HAVE_CLOSE_RANGE +static inline int close_range(unsigned int first, unsigned int last) +{ + return syscall(SYS_close_range, first, last); +} +# endif +# define HAVE_CLOSE_RANGE 1 +# endif /* SYS_close_range */ +#endif /* __linux__ */ + extern void close_all_fds(const int exclude[], size_t exsz); #define UL_COPY_READ_ERROR (-1) diff --git a/login-utils/login.c b/login-utils/login.c index 0a325697f5..ec8ce0fdf6 100644 --- a/login-utils/login.c +++ b/login-utils/login.c @@ -1294,9 +1294,11 @@ static void initialize(int argc, char **argv, struct login_context *cxt) {"version", no_argument, NULL, 'V'}, {NULL, 0, NULL, 0} }; +#ifndef HAVE_CLOSE_RANGE const int wanted_fds[] = { STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO }; +#endif timeout = (unsigned int)getlogindefs_num("LOGIN_TIMEOUT", LOGIN_TIMEOUT); @@ -1365,8 +1367,11 @@ static void initialize(int argc, char **argv, struct login_context *cxt) *p++ = ' '; #endif } - +#ifdef HAVE_CLOSE_RANGE + close_range(STDERR_FILENO + 1, ~0U); +#else close_all_fds(wanted_fds, ARRAY_SIZE(wanted_fds)); +#endif } int main(int argc, char **argv)