From patchwork Sat Nov 6 15:35:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Bugaev X-Patchwork-Id: 47162 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2E2FB3857811 for ; Sat, 6 Nov 2021 15:36:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2E2FB3857811 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1636212990; bh=JKnFPDU6tLs034VAIRwA8ppqI5hpptyzJfyUB7208eo=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=SfBe+2WkBxK/lzzcx8uYoUE59y5DSE7EkWtjMjMirhVKG2fVFcIzMueIsEaXrvzKP 3DbI+lfWyRAvJoLCEG4MY7qKF9BN+KeJk+JaWntSY/9fsQxgRCDAHNEUcbud3na6JX Kf1iGe6isMel/qej5auH/bNUwNvlGiKdfT0RV7ZM= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-lf1-x129.google.com (mail-lf1-x129.google.com [IPv6:2a00:1450:4864:20::129]) by sourceware.org (Postfix) with ESMTPS id E238A3858401 for ; Sat, 6 Nov 2021 15:36:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E238A3858401 Received: by mail-lf1-x129.google.com with SMTP id bu18so25318055lfb.0 for ; Sat, 06 Nov 2021 08:36:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JKnFPDU6tLs034VAIRwA8ppqI5hpptyzJfyUB7208eo=; b=z/SDma1LPajDQvDgNRqLah4TVasODj7Bot+5O9PREq8Xs89kA2RlmaMihFrdDYMT4d QVaVg36dHZx52QdICQkuIhIGEoLRBHK+lMxep96C3Ra+ahjbNc0gOg/sVO+L9bwnds/q AMHhMUEKeOQiSlS48uEH9XZSqThY51/dLdrXGSSdU420giEK5ApYVQ16YUS57BOR0T00 ccyWaZvlqKrh7yUS264XGTsv+DzFPewwE+pJSSC2r67/E28712l5ZDVK2Law23Jv6wM0 j0tEpTHuwaRZkr9r0M/9zt+XgO1iEP31G5xfSo5d3TymM/lF6SCyUqozm1tgfpOymWJ9 AVGw== X-Gm-Message-State: AOAM531/VP9IE6A5S4jZjUfVvksGeuWRCimdvH14usq1slTZTbqjpNlz GPlhm7gahK8a2sd9Jk7Wxr8Q+g7QNKpgwxoG X-Google-Smtp-Source: ABdhPJy5v4NfdPUF4YuiviVgsvoIbmpx/2rs6Y2xmN3F8rQkO+K0isr6yC6B6MNgqBw5fFmrLvmNww== X-Received: by 2002:ac2:58f7:: with SMTP id v23mr10421782lfo.636.1636212964310; Sat, 06 Nov 2021 08:36:04 -0700 (PDT) Received: from localhost.localdomain ([2a02:2168:b344:a600:5ad0:33f0:d4aa:9f66]) by smtp.googlemail.com with ESMTPSA id a1sm1191015lfi.167.2021.11.06.08.36.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 Nov 2021 08:36:03 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH] hurd: Implement close_range and closefrom Date: Sat, 6 Nov 2021 18:35:24 +0300 Message-Id: <20211106153524.82700-1-bugaevc@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211106121608.n2cafnwzlbdy5uaw@begin> References: <20211106121608.n2cafnwzlbdy5uaw@begin> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Sergey Bugaev via Libc-alpha From: Sergey Bugaev Reply-To: Sergey Bugaev Cc: Sergey Bugaev , bug-hurd@gnu.org, samuel.thibault@gnu.org, liberamenso10000@gmail.com Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" 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 --- 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 , 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..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