diff options
author | Sergey Bugaev <bugaevc@gmail.com> | 2021-11-06 18:35:24 +0300 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2021-11-07 16:16:11 +0100 |
commit | f2c996597d7441c1b9b390216c693ecfde3a8588 (patch) | |
tree | 5296e6795bc0101dd2cfd95949b62fdccbacd1df /sysdeps/mach/hurd/close_range.c | |
parent | 475b63702ef38b69558fc3d31a0b66776a70f1d3 (diff) | |
download | glibc-f2c996597d7441c1b9b390216c693ecfde3a8588.tar.gz glibc-f2c996597d7441c1b9b390216c693ecfde3a8588.tar.xz glibc-f2c996597d7441c1b9b390216c693ecfde3a8588.zip |
hurd: Implement close_range and closefrom
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> Message-Id: <20211106153524.82700-1-bugaevc@gmail.com>
Diffstat (limited to 'sysdeps/mach/hurd/close_range.c')
-rw-r--r-- | sysdeps/mach/hurd/close_range.c | 67 |
1 files changed, 67 insertions, 0 deletions
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) |