aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--include/unistd.h1
-rw-r--r--io/Makefile4
-rw-r--r--io/Versions3
-rw-r--r--io/closefrom.c34
-rw-r--r--io/tst-closefrom.c152
-rw-r--r--manual/llio.texi10
-rw-r--r--posix/unistd.h6
-rw-r--r--sysdeps/mach/hurd/i386/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/Makefile3
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/alpha/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/arc/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/arm/be/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/arm/le/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/closefrom.c35
-rw-r--r--sysdeps/unix/sysv/linux/closefrom_fallback.c97
-rw-r--r--sysdeps/unix/sysv/linux/csky/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/i386/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/ia64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/be/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/le/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/nios2/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/sh/be/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/sh/le/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist1
44 files changed, 380 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index be04b217fe..e01a245ac5 100644
--- a/NEWS
+++ b/NEWS
@@ -63,6 +63,10 @@ Major new features:
* On Linux, the close_range function has been added. It allows efficiently
closing a range of file descriptors on recent kernels (version 5.9).
+* The function closefrom has been added. It closes all file descriptors
+ greater than given integer. This function is a GNU extension, although it
+ also present in other systems.
+
Deprecated and removed features, and other changes affecting compatibility:
* The function pthread_mutex_consistent_np has been deprecated; programs
diff --git a/include/unistd.h b/include/unistd.h
index 691405a945..114a43128e 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -158,6 +158,7 @@ extern int __brk (void *__addr) attribute_hidden;
extern int __close (int __fd);
libc_hidden_proto (__close)
extern int __libc_close (int __fd);
+extern _Bool __closefrom_fallback (int __lowfd) attribute_hidden;
extern ssize_t __read (int __fd, void *__buf, size_t __nbytes);
libc_hidden_proto (__read)
extern ssize_t __write (int __fd, const void *__buf, size_t __n);
diff --git a/io/Makefile b/io/Makefile
index 1a16990205..ebb7d56d67 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -56,7 +56,8 @@ routines := \
sendfile sendfile64 copy_file_range \
utimensat futimens file_change_detection \
fts64-time64 \
- ftw64-time64
+ ftw64-time64 \
+ closefrom
others := pwd
test-srcs := ftwtest ftwtest-time64
@@ -77,6 +78,7 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
tst-lutimes \
tst-futimens \
tst-utimensat \
+ tst-closefrom \
tests-time64 := \
tst-futimens-time64 \
diff --git a/io/Versions b/io/Versions
index 88caf76bbc..4e19540885 100644
--- a/io/Versions
+++ b/io/Versions
@@ -137,6 +137,9 @@ libc {
stat; stat64; fstat; fstat64; lstat; lstat64; fstatat; fstatat64;
mknod; mknodat;
}
+ GLIBC_2.34 {
+ closefrom;
+ }
GLIBC_PRIVATE {
__libc_fcntl64;
__fcntl_nocancel;
diff --git a/io/closefrom.c b/io/closefrom.c
new file mode 100644
index 0000000000..01660a7531
--- /dev/null
+++ b/io/closefrom.c
@@ -0,0 +1,34 @@
+/* Close a range of file descriptors.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <not-cancel.h>
+
+void
+__closefrom (int lowfd)
+{
+ int maxfd = __getdtablesize ();
+ if (maxfd == -1)
+ __fortify_fail ("closefrom failed to get the file descriptor table size");
+
+ for (int i = 0; i < maxfd; i++)
+ if (i >= lowfd)
+ __close_nocancel_nostatus (i);
+}
+weak_alias (__closefrom, closefrom)
diff --git a/io/tst-closefrom.c b/io/tst-closefrom.c
new file mode 100644
index 0000000000..d4c187073c
--- /dev/null
+++ b/io/tst-closefrom.c
@@ -0,0 +1,152 @@
+/* Smoke test for the closefrom.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+#include <support/check.h>
+#include <support/descriptors.h>
+#include <support/xunistd.h>
+
+#include <array_length.h>
+
+#define NFDS 100
+
+static int
+open_multiple_temp_files (void)
+{
+ /* Check if the temporary file descriptor has no no gaps. */
+ int lowfd = xopen ("/dev/null", O_RDONLY, 0600);
+ for (int i = 1; i <= NFDS; i++)
+ TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600), lowfd + i);
+ return lowfd;
+}
+
+static int
+closefrom_test (void)
+{
+ struct support_descriptors *descrs = support_descriptors_list ();
+
+ int lowfd = open_multiple_temp_files ();
+
+ const int maximum_fd = lowfd + NFDS;
+ const int half_fd = lowfd + NFDS / 2;
+ const int gap = maximum_fd / 4;
+
+ /* Close half of the descriptors and check result. */
+ closefrom (half_fd);
+
+ for (int i = half_fd; i <= maximum_fd; i++)
+ {
+ TEST_COMPARE (fcntl (i, F_GETFL), -1);
+ TEST_COMPARE (errno, EBADF);
+ }
+ for (int i = 0; i < half_fd; i++)
+ TEST_VERIFY (fcntl (i, F_GETFL) > -1);
+
+ /* Create some gaps, close up to a threshold, and check result. */
+ xclose (lowfd + 35);
+ xclose (lowfd + 38);
+ xclose (lowfd + 42);
+ xclose (lowfd + 46);
+
+ /* Close half of the descriptors and check result. */
+ closefrom (gap);
+ for (int i = gap + 1; i < maximum_fd; i++)
+ {
+ TEST_COMPARE (fcntl (i, F_GETFL), -1);
+ TEST_COMPARE (errno, EBADF);
+ }
+ for (int i = 0; i < gap; i++)
+ TEST_VERIFY (fcntl (i, F_GETFL) > -1);
+
+ /* Close the remmaining but the last one. */
+ closefrom (lowfd + 1);
+ for (int i = lowfd + 1; i <= maximum_fd; i++)
+ {
+ TEST_COMPARE (fcntl (i, F_GETFL), -1);
+ TEST_COMPARE (errno, EBADF);
+ }
+ TEST_VERIFY (fcntl (lowfd, F_GETFL) > -1);
+
+ /* Close the last one. */
+ closefrom (lowfd);
+ TEST_COMPARE (fcntl (lowfd, F_GETFL), -1);
+ TEST_COMPARE (errno, EBADF);
+
+ /* Double check by check the /proc. */
+ support_descriptors_check (descrs);
+ support_descriptors_free (descrs);
+
+ return 0;
+}
+
+/* Check if closefrom works even when no new file descriptors can be
+ created. */
+static int
+closefrom_test_file_desc_limit (void)
+{
+ int max_fd = NFDS;
+ {
+ struct rlimit rl;
+ if (getrlimit (RLIMIT_NOFILE, &rl) == -1)
+ FAIL_EXIT1 ("getrlimit (RLIMIT_NOFILE): %m");
+
+ max_fd = (rl.rlim_cur < max_fd ? rl.rlim_cur : max_fd);
+ rl.rlim_cur = max_fd;
+
+ if (setrlimit (RLIMIT_NOFILE, &rl) == 1)
+ FAIL_EXIT1 ("setrlimit (RLIMIT_NOFILE): %m");
+ }
+
+ /* Exhauste the file descriptor limit. */
+ int lowfd = xopen ("/dev/null", O_RDONLY, 0600);
+ for (;;)
+ {
+ int fd = open ("/dev/null", O_RDONLY, 0600);
+ if (fd == -1)
+ {
+ if (errno != EMFILE)
+ FAIL_EXIT1 ("open: %m");
+ break;
+ }
+ TEST_VERIFY_EXIT (fd < max_fd);
+ }
+
+ closefrom (lowfd);
+ for (int i = lowfd; i < NFDS; i++)
+ {
+ TEST_COMPARE (fcntl (i, F_GETFL), -1);
+ TEST_COMPARE (errno, EBADF);
+ }
+
+ return 0;
+}
+
+static int
+do_test (void)
+{
+ closefrom_test ();
+ closefrom_test_file_desc_limit ();
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/manual/llio.texi b/manual/llio.texi
index e21a71fdd0..2c59f6badf 100644
--- a/manual/llio.texi
+++ b/manual/llio.texi
@@ -334,6 +334,16 @@ The kernel does not implement the required functionality.
@end table
@end deftypefun
+@deftypefun void closefrom (int @var{lowfd})
+@standards{GNU, unistd.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+
+The function @code{closefrom} closes all file descriptors larger than or equal
+to @var{lowfd} then @var{lowfd}. This function is similar to calling
+@code{close} for all open file descriptors not less than @var{lowfd}.
+
+Already closed file descriptors are ignored.
+@end deftypefun
@node I/O Primitives
@section Input and Output Primitives
diff --git a/posix/unistd.h b/posix/unistd.h
index 217c6c5363..3dca65732f 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -357,6 +357,12 @@ extern __off64_t lseek64 (int __fd, __off64_t __offset, int __whence)
__THROW. */
extern int close (int __fd);
+#ifdef __USE_MISC
+/* Close all open file descriptors greater than or equal to LOWFD.
+ Negative LOWFD is clamped to 0. */
+extern void closefrom (int __lowfd) __THROW;
+#endif
+
/* Read NBYTES into BUF from FD. Return the
number read, -1 for errors or 0 for EOF.
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index fcfe64f26b..475bf2d6e9 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2225,6 +2225,7 @@ GLIBC_2.34 _Fork F
GLIBC_2.34 __isnanf128 F
GLIBC_2.34 __libc_start_main F
GLIBC_2.34 _hurd_libc_proc_init F
+GLIBC_2.34 closefrom F
GLIBC_2.34 dladdr F
GLIBC_2.34 dladdr1 F
GLIBC_2.34 dlclose F
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index e308711168..d45a16af8b 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -64,7 +64,8 @@ sysdep_routines += adjtimex clone umount umount2 readahead sysctl \
pselect32 \
xstat fxstat lxstat xstat64 fxstat64 lxstat64 \
fxstatat fxstatat64 \
- xmknod xmknodat convert_scm_timestamps
+ xmknod xmknodat convert_scm_timestamps \
+ closefrom_fallback
CFLAGS-gethostid.c = -fexceptions
CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 428b23fc65..5d5dc5ae57 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2408,6 +2408,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index d5c24d09ee..5f863c7d46 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2507,6 +2507,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 6213e42bba..e9349e550f 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -2167,6 +2167,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 37c395e4cb..cdfa582b30 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -301,6 +301,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index dd850ce035..83bf3466da 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -298,6 +298,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/closefrom.c b/sysdeps/unix/sysv/linux/closefrom.c
new file mode 100644
index 0000000000..f5d7342c2c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/closefrom.c
@@ -0,0 +1,35 @@
+/* Close a range of file descriptors. Linux version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <unistd.h>
+
+void
+__closefrom (int lowfd)
+{
+ int l = MAX (0, lowfd);
+
+ int r = __close_range (l, ~0U, 0);
+ if (r == 0)
+ return;
+
+ if (!__closefrom_fallback (l))
+ __fortify_fail ("closefrom failed to close a file descriptor");
+}
+weak_alias (__closefrom, closefrom)
diff --git a/sysdeps/unix/sysv/linux/closefrom_fallback.c b/sysdeps/unix/sysv/linux/closefrom_fallback.c
new file mode 100644
index 0000000000..61e71d388d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/closefrom_fallback.c
@@ -0,0 +1,97 @@
+/* Close a range of file descriptors. Linux version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <arch-fd_to_filename.h>
+#include <dirent.h>
+#include <not-cancel.h>
+#include <stdbool.h>
+
+/* Fallback code: iterates over /proc/self/fd, closing each file descriptor
+ that fall on the criteria. */
+_Bool
+__closefrom_fallback (int from)
+{
+ bool ret = false;
+
+ int dirfd = __open_nocancel (FD_TO_FILENAME_PREFIX, O_RDONLY | O_DIRECTORY,
+ 0);
+ if (dirfd == -1)
+ {
+ /* The closefrom should work even when process can't open new files. */
+ if (errno == ENOENT)
+ goto err;
+
+ for (int i = from; i < INT_MAX; i++)
+ {
+ int r = __close_nocancel (i);
+ if (r == 0 || (r == -1 && errno != EBADF))
+ break;
+ }
+
+ dirfd = __open_nocancel (FD_TO_FILENAME_PREFIX, O_RDONLY | O_DIRECTORY,
+ 0);
+ if (dirfd == -1)
+ goto err;
+ }
+
+ char buffer[1024];
+ while (true)
+ {
+ ssize_t ret = __getdents64 (dirfd, buffer, sizeof (buffer));
+ if (ret == -1)
+ goto err;
+ else if (ret == 0)
+ break;
+
+ /* If any file descriptor is closed it resets the /proc/self position
+ read again from the start (to obtain any possible kernel update). */
+ bool closed = false;
+ char *begin = buffer, *end = buffer + ret;
+ while (begin != end)
+ {
+ unsigned short int d_reclen;
+ memcpy (&d_reclen, begin + offsetof (struct dirent64, d_reclen),
+ sizeof (d_reclen));
+ const char *dname = begin + offsetof (struct dirent64, d_name);
+ begin += d_reclen;
+
+ if (dname[0] == '.')
+ continue;
+
+ int fd = 0;
+ for (const char *s = dname; (unsigned int) (*s) - '0' < 10; s++)
+ fd = 10 * fd + (*s - '0');
+
+ if (fd == dirfd || fd < from)
+ continue;
+
+ /* We ignore close errors because EBADF, EINTR, and EIO means the
+ descriptor has been released. */
+ __close_nocancel (fd);
+ closed = true;
+ }
+
+ if (closed && __lseek (dirfd, 0, SEEK_SET) < 0)
+ goto err;
+ }
+
+ ret = true;
+err:
+ __close_nocancel (dirfd);
+ return ret;
+}
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 48dc96e2d5..705b696af0 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2433,6 +2433,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 13772d42d3..db77e473c4 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2386,6 +2386,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 6613f4c5f0..126c8f68d4 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2570,6 +2570,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 06d096d945..6ca9645d1b 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2345,6 +2345,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index dc2466f3cd..0a5d6dea8c 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -302,6 +302,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index d425dbad0b..11e4f01d99 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2513,6 +2513,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index f1fc79525c..6efe53a906 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2484,6 +2484,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 7cf1c864b7..3b1a49cf7f 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2481,6 +2481,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 41b7927b86..625638175b 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2478,6 +2478,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 91f06d23ca..c812e5ca13 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2476,6 +2476,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index a4d3e06941..43296b21d7 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2484,6 +2484,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 3e96b69ba4..12652d6c1e 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2396,6 +2396,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 3618eaa4e0..676dce59fa 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2523,6 +2523,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 3951054b61..959418aa48 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2540,6 +2540,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 4c2adbd8ab..405b9b9c49 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2573,6 +2573,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index e9d30b1ed7..e60fe8917d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2309,6 +2309,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 81c1eac79c..0f86da7288 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2604,6 +2604,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 6fa30b247b..e1f3be2f85 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -2169,6 +2169,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 7c20b71f7a..bf6b44d486 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2369,6 +2369,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index fe0c9a2d06..1437ff7adb 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2538,6 +2538,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index da52d75a7d..68e49fa37f 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2346,6 +2346,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 6f022d19e8..9ec571d9d4 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2393,6 +2393,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index a4934d88e9..f1114f1852 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2390,6 +2390,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 684e9d7b06..e63a58eb95 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2533,6 +2533,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index af10195edb..25f1526c77 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2368,6 +2368,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index b5e2710a97..88a5b0b38e 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2324,6 +2324,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index ecd0b4efb8..ff219a825c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2423,6 +2423,7 @@ GLIBC_2.34 aio_write F
GLIBC_2.34 aio_write64 F
GLIBC_2.34 call_once F
GLIBC_2.34 close_range F
+GLIBC_2.34 closefrom F
GLIBC_2.34 cnd_broadcast F
GLIBC_2.34 cnd_destroy F
GLIBC_2.34 cnd_init F