]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
login: use close_range() system call when possible
authorSami Kerola <kerolasa@iki.fi>
Sat, 14 Nov 2020 12:55:10 +0000 (12:55 +0000)
committerSami Kerola <kerolasa@iki.fi>
Thu, 3 Dec 2020 20:09:14 +0000 (20:09 +0000)
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 <kerolasa@iki.fi>
configure.ac
include/fileutils.h
login-utils/login.c

index 8f026c85a008856ecf8e935411715ade3af46884..a2ac7a6da4248c23640906c9f15a69215afc053d 100644 (file)
@@ -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"])]
index 618bf39967e01815526b74ec21aa60a5f2cd186b..1de214bcad2a93a5df9c8bd48e9ab78a612583b3 100644 (file)
@@ -72,6 +72,20 @@ static inline struct dirent *xreaddir(DIR *dp)
        return d;
 }
 
+#if defined(__linux__)
+# include <sys/syscall.h>
+# if defined(SYS_close_range)
+#  include <sys/types.h>
+#  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)
index 0a325697f513ad4883078311b21cabcbfd9adef4..ec8ce0fdf6b0d0655a2029c67017b7196445a3da 100644 (file)
@@ -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)