diff --git a/sysdeps/mach/hurd/Makefile b/sysdeps/mach/hurd/Makefile index 17bb643c18..9acbe80f26 100644 --- a/sysdeps/mach/hurd/Makefile +++ b/sysdeps/mach/hurd/Makefile @@ -196,7 +196,7 @@ sysdep_routines += cthreads endif ifeq (io, $(subdir)) -sysdep_routines += f_setlk close_nocancel close_nocancel_nostatus \ +sysdep_routines += f_setlk close_nocancel close_nocancel_nostatus close_range \ 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..d75e674bb6 100644 --- a/sysdeps/mach/hurd/Versions +++ b/sysdeps/mach/hurd/Versions @@ -10,6 +10,9 @@ libc { GLIBC_2.32 { mremap; } + GLIBC_2.35 { + 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 , 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 + . */ + +#ifndef _UNISTD_H +# error "Never include directly; use 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 + . */ + +#include +#include +#include + +/* 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 + . */ + +#include +#include + +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..d8375b1073 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2286,6 +2286,7 @@ GLIBC_2.34 shm_open F GLIBC_2.34 shm_unlink F GLIBC_2.34 timespec_getres F GLIBC_2.35 __memcmpeq F +GLIBC_2.35 close_range F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F