[PATCH] hurd: Implement close_range and closefrom
Samuel Thibault
samuel.thibault@gnu.org
Sun Nov 7 15:17:36 GMT 2021
Hello,
Applied, thanks!
(I have just fixed the symbol version: glibc 2.34 is already out, we are
preparing glibc 2.35).
Samuel
Sergey Bugaev, le sam. 06 nov. 2021 18:35:24 +0300, a ecrit:
> The close_range () function implements the same API as the Linux and
> FreeBSD syscalls. It operates atomically and reliably. The specified
> upper bound is clamped to the actual size of the file descriptor table;
> it is expected that the most common use case is with last = UINT_MAX.
>
> Like in the Linux syscall, it is also possible to pass the
> CLOSE_RANGE_CLOEXEC flag to mark the file descriptors in the range
> cloexec instead of acually closing them.
>
> Also, add a Hurd version of the closefrom () function. Since unlike on
> Linux, close_range () cannot fail due to being unuspported by the
> running kernel, a fallback implementation is never necessary.
>
> Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
> ---
> sysdeps/mach/hurd/Makefile | 1 +
> sysdeps/mach/hurd/Versions | 3 ++
> sysdeps/mach/hurd/bits/unistd_ext.h | 34 +++++++++++++++
> sysdeps/mach/hurd/close_range.c | 67 +++++++++++++++++++++++++++++
> sysdeps/mach/hurd/closefrom.c | 29 +++++++++++++
> sysdeps/mach/hurd/i386/libc.abilist | 1 +
> 6 files changed, 135 insertions(+)
> create mode 100644 sysdeps/mach/hurd/bits/unistd_ext.h
> create mode 100644 sysdeps/mach/hurd/close_range.c
> create mode 100644 sysdeps/mach/hurd/closefrom.c
>
> diff --git a/sysdeps/mach/hurd/Makefile b/sysdeps/mach/hurd/Makefile
> index 17bb643c18..595002bc6a 100644
> --- a/sysdeps/mach/hurd/Makefile
> +++ b/sysdeps/mach/hurd/Makefile
> @@ -197,6 +197,7 @@ endif
>
> ifeq (io, $(subdir))
> sysdep_routines += f_setlk close_nocancel close_nocancel_nostatus \
> + close_range closefrom \
> fcntl_nocancel open_nocancel openat_nocancel read_nocancel \
> pread64_nocancel write_nocancel pwrite64_nocancel \
> wait4_nocancel \
> diff --git a/sysdeps/mach/hurd/Versions b/sysdeps/mach/hurd/Versions
> index 89dabd0485..ac38ed44dd 100644
> --- a/sysdeps/mach/hurd/Versions
> +++ b/sysdeps/mach/hurd/Versions
> @@ -10,6 +10,9 @@ libc {
> GLIBC_2.32 {
> mremap;
> }
> + GLIBC_2.34 {
> + close_range;
> + }
> GLIBC_PRIVATE {
> # Functions shared with the dynamic linker
> __access; __access_noerrno; __libc_read; __libc_write; __libc_lseek64;
> diff --git a/sysdeps/mach/hurd/bits/unistd_ext.h b/sysdeps/mach/hurd/bits/unistd_ext.h
> new file mode 100644
> index 0000000000..288f504a3c
> --- /dev/null
> +++ b/sysdeps/mach/hurd/bits/unistd_ext.h
> @@ -0,0 +1,34 @@
> +/* System-specific extensions of <unistd.h>, Hurd version.
> + Copyright (C) 2019-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/>. */
> +
> +#ifndef _UNISTD_H
> +# error "Never include <bits/unistd_ext.h> directly; use <unistd.h> instead."
> +#endif
> +
> +#ifdef __USE_GNU
> +
> +/* Set the FD_CLOEXEC bit instead of closing the file descriptor. */
> +#define CLOSE_RANGE_CLOEXEC (1U << 2)
> +
> +/* Close the file descriptors from FIRST up to LAST, inclusive.
> + If CLOSE_RANGE_CLOEXEC is set in FLAGS, set the FD_CLOEXEC flag
> + instead of closing. */
> +extern int close_range (unsigned int __first, unsigned int __last,
> + int __flags) __THROW;
> +
> +#endif /* __USE_GNU */
> diff --git a/sysdeps/mach/hurd/close_range.c b/sysdeps/mach/hurd/close_range.c
> new file mode 100644
> index 0000000000..d6a2eab086
> --- /dev/null
> +++ b/sysdeps/mach/hurd/close_range.c
> @@ -0,0 +1,67 @@
> +/* 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 <unistd.h>
> +#include <hurd.h>
> +#include <hurd/fd.h>
> +
> +/* Close the file descriptors from FIRST up to LAST, inclusive.
> + If CLOSE_RANGE_CLOEXEC is set in FLAGS, set the FD_CLOEXEC flag
> + instead of closing. */
> +int
> +__close_range (unsigned int first, unsigned int last,
> + int flags)
> +{
> + int i;
> +
> + if (first > last)
> + return __hurd_fail (EINVAL);
> + if (flags & ~CLOSE_RANGE_CLOEXEC)
> + return __hurd_fail (EINVAL);
> +
> + HURD_CRITICAL_BEGIN;
> + __mutex_lock (&_hurd_dtable_lock);
> +
> + for (i = first; i <= last && i < _hurd_dtablesize; i++)
> + {
> + struct hurd_fd *fd = _hurd_dtable[i];
> +
> + if (fd == NULL || fd->port.port == MACH_PORT_NULL)
> + continue;
> +
> + __spin_lock (&fd->port.lock);
> +
> + if (flags & CLOSE_RANGE_CLOEXEC)
> + fd->flags |= FD_CLOEXEC;
> + else
> + {
> + _hurd_port_set (&fd->ctty, MACH_PORT_NULL);
> + _hurd_port_locked_set (&fd->port, MACH_PORT_NULL);
> + }
> +
> + __spin_unlock (&fd->port.lock);
> + }
> +
> + __mutex_unlock (&_hurd_dtable_lock);
> + HURD_CRITICAL_END;
> +
> + return 0;
> +}
> +
> +libc_hidden_def (__close_range)
> +strong_alias (__close_range, __libc_close_range)
> +weak_alias (__close_range, close_range)
> diff --git a/sysdeps/mach/hurd/closefrom.c b/sysdeps/mach/hurd/closefrom.c
> new file mode 100644
> index 0000000000..5d667cf6c4
> --- /dev/null
> +++ b/sysdeps/mach/hurd/closefrom.c
> @@ -0,0 +1,29 @@
> +/* Close a range of file descriptors. Hurd 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 <unistd.h>
> +#include <sys/param.h>
> +
> +void
> +__closefrom (int lowfd)
> +{
> + int l = MAX (0, lowfd);
> +
> + (void) __close_range (l, ~0U, 0);
> +}
> +weak_alias (__closefrom, closefrom)
> diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
> index e849d6fa35..729c29f0e1 100644
> --- a/sysdeps/mach/hurd/i386/libc.abilist
> +++ b/sysdeps/mach/hurd/i386/libc.abilist
> @@ -2240,6 +2240,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 close_range F
> GLIBC_2.34 closefrom F
> GLIBC_2.34 dladdr F
> GLIBC_2.34 dladdr1 F
> --
> 2.33.1
More information about the Libc-alpha
mailing list