From patchwork Mon Nov 7 20:16:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 60146 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 8696E385828C for ; Mon, 7 Nov 2022 20:17:08 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from sonata.ens-lyon.org (sonata.ens-lyon.org [140.77.166.138]) by sourceware.org (Postfix) with ESMTPS id 976DF3858C33 for ; Mon, 7 Nov 2022 20:16:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 976DF3858C33 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ens-lyon.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=bounce.ens-lyon.org Received: from localhost (localhost [127.0.0.1]) by sonata.ens-lyon.org (Postfix) with ESMTP id A37DC20105; Mon, 7 Nov 2022 21:16:50 +0100 (CET) Received: from sonata.ens-lyon.org ([127.0.0.1]) by localhost (sonata.ens-lyon.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 77aUY9eD9zsC; Mon, 7 Nov 2022 21:16:50 +0100 (CET) Received: from begin (lfbn-bor-1-376-208.w109-215.abo.wanadoo.fr [109.215.91.208]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by sonata.ens-lyon.org (Postfix) with ESMTPSA id 241C320101; Mon, 7 Nov 2022 21:16:50 +0100 (CET) Received: from samy by begin with local (Exim 4.96) (envelope-from ) id 1os8Y5-0003zx-2c; Mon, 07 Nov 2022 21:16:49 +0100 From: Samuel Thibault To: libc-alpha@sourceware.org Cc: Samuel Thibault , commit-hurd@gnu.org Subject: [hurd,commited] hurd: Add sigtimedwait and sigwaitinfo support Date: Mon, 7 Nov 2022 21:16:48 +0100 Message-Id: <20221107201648.15362-1-samuel.thibault@ens-lyon.org> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 X-Spam-Status: No, score=-13.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This simply needed to add the timeout parameter to mach_msg, and copy information from struct hurd_signal_detail. --- sysdeps/mach/hurd/sigtimedwait.c | 170 +++++++++++++++++++++++++++++++ sysdeps/mach/hurd/sigwait.c | 121 ++-------------------- sysdeps/mach/hurd/sigwaitinfo.c | 28 +++++ 3 files changed, 207 insertions(+), 112 deletions(-) create mode 100644 sysdeps/mach/hurd/sigtimedwait.c create mode 100644 sysdeps/mach/hurd/sigwaitinfo.c diff --git a/sysdeps/mach/hurd/sigtimedwait.c b/sysdeps/mach/hurd/sigtimedwait.c new file mode 100644 index 0000000000..cc5b383ea6 --- /dev/null +++ b/sysdeps/mach/hurd/sigtimedwait.c @@ -0,0 +1,170 @@ +/* Implementation of sigtimedwait function from POSIX.1b. + Copyright (C) 1996-2022 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 +#include +#include +#include +#include + +int +__sigtimedwait (const sigset_t *set, siginfo_t *info, + const struct timespec *timeout) +{ + struct hurd_sigstate *ss; + sigset_t mask, ready, blocked; + int signo = 0; + struct hurd_signal_preemptor preemptor; + jmp_buf buf; + mach_port_t wait; + mach_msg_header_t msg; + int cancel_oldtype; + mach_msg_option_t option = 0; + mach_msg_timeout_t ms = MACH_MSG_TIMEOUT_NONE; + + sighandler_t + preempt_fun (struct hurd_signal_preemptor *pe, + struct hurd_sigstate *ss, + int *sigp, + struct hurd_signal_detail *detail) + { + if (signo) + /* We've already been run; don't interfere. */ + return SIG_ERR; + + signo = *sigp; + + if (info) + { + info->si_signo = signo; + info->si_errno = detail->error; + info->si_code = detail->code; + + /* XXX */ + info->si_pid = -1; + info->si_uid = -1; + info->si_addr = (void *) NULL; + info->si_status = 0; + info->si_band = 0; + info->si_value.sival_int = 0; + } + + /* Make sure this is all kosher */ + assert (__sigismember (&mask, signo)); + + /* Restore the blocking mask. */ + ss->blocked = blocked; + + return pe->handler; + } + + void + handler (int sig) + { + assert (sig == signo); + longjmp (buf, 1); + } + + wait = __mach_reply_port (); + + if (set != NULL) + /* Crash before locking */ + mask = *set; + else + __sigemptyset (&mask); + + ss = _hurd_self_sigstate (); + cancel_oldtype = LIBC_CANCEL_ASYNC(); + _hurd_sigstate_lock (ss); + + /* See if one of these signals is currently pending. */ + sigset_t pending = _hurd_sigstate_pending (ss); + __sigandset (&ready, &pending, &mask); + if (! __sigisemptyset (&ready)) + { + for (signo = 1; signo < NSIG; signo++) + if (__sigismember (&ready, signo)) + { + __sigdelset (&ready, signo); + goto all_done; + } + /* Huh? Where'd it go? */ + abort (); + } + + /* Wait for one of them to show up. */ + + if (!setjmp (buf)) + { + /* Make the preemptor */ + preemptor.signals = mask; + preemptor.first = 0; + preemptor.last = -1; + preemptor.preemptor = preempt_fun; + preemptor.handler = handler; + + /* Install this preemptor */ + preemptor.next = ss->preemptors; + ss->preemptors = &preemptor; + + /* Unblock the expected signals */ + blocked = ss->blocked; + ss->blocked &= ~mask; + + _hurd_sigstate_unlock (ss); + + if (timeout) + { + option |= MACH_RCV_TIMEOUT, + ms = timeout->tv_sec * 1000 + + (timeout->tv_nsec + 999999) / 1000000; + } + + /* Wait. */ + __mach_msg (&msg, MACH_RCV_MSG | option, 0, sizeof (msg), wait, + ms, MACH_PORT_NULL); + + if (!(option & MACH_RCV_TIMEOUT)) + abort (); + + /* Timed out. */ + signo = __hurd_fail (EAGAIN); + } + else + { + assert (signo); + + _hurd_sigstate_lock (ss); + + /* Delete our preemptor. */ + assert (ss->preemptors == &preemptor); + ss->preemptors = preemptor.next; + } + + +all_done: + _hurd_sigstate_unlock (ss); + LIBC_CANCEL_RESET (cancel_oldtype); + + __mach_port_destroy (__mach_task_self (), wait); + return signo; +} +libc_hidden_def (__sigtimedwait) +weak_alias (__sigtimedwait, sigtimedwait) diff --git a/sysdeps/mach/hurd/sigwait.c b/sysdeps/mach/hurd/sigwait.c index 9d2dfe13ee..caf1aef933 100644 --- a/sysdeps/mach/hurd/sigwait.c +++ b/sysdeps/mach/hurd/sigwait.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2022 Free Software Foundation, Inc. +/* Copyright (C) 2022 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 @@ -15,128 +15,25 @@ License along with the GNU C Library; if not, see . */ -#include +#include #include -#include -#include -#include -#include -#include /* Select any of pending signals from SET or wait for any to arrive. */ int __sigwait (const sigset_t *set, int *sig) { - struct hurd_sigstate *ss; - sigset_t mask, ready, blocked; - int signo = 0; - struct hurd_signal_preemptor preemptor; - jmp_buf buf; - mach_port_t wait; - mach_msg_header_t msg; - int cancel_oldtype; + int ret; - sighandler_t - preempt_fun (struct hurd_signal_preemptor *pe, - struct hurd_sigstate *ss, - int *sigp, - struct hurd_signal_detail *detail) - { - if (signo) - /* We've already been run; don't interfere. */ - return SIG_ERR; + ret = __sigtimedwait (set, NULL, NULL); - signo = *sigp; + if (ret < 0) + return -1; - /* Make sure this is all kosher */ - assert (__sigismember (&mask, signo)); + if (!ret) + return __hurd_fail(EAGAIN); - /* Restore the blocking mask. */ - ss->blocked = blocked; - - return pe->handler; - } - - void - handler (int sig) - { - assert (sig == signo); - longjmp (buf, 1); - } - - wait = __mach_reply_port (); - - if (set != NULL) - /* Crash before locking */ - mask = *set; - else - __sigemptyset (&mask); - - ss = _hurd_self_sigstate (); - cancel_oldtype = LIBC_CANCEL_ASYNC(); - _hurd_sigstate_lock (ss); - - /* See if one of these signals is currently pending. */ - sigset_t pending = _hurd_sigstate_pending (ss); - __sigandset (&ready, &pending, &mask); - if (! __sigisemptyset (&ready)) - { - for (signo = 1; signo < NSIG; signo++) - if (__sigismember (&ready, signo)) - { - __sigdelset (&ready, signo); - goto all_done; - } - /* Huh? Where'd it go? */ - abort (); - } - - /* Wait for one of them to show up. */ - - if (!setjmp (buf)) - { - /* Make the preemptor */ - preemptor.signals = mask; - preemptor.first = 0; - preemptor.last = -1; - preemptor.preemptor = preempt_fun; - preemptor.handler = handler; - - /* Install this preemptor */ - preemptor.next = ss->preemptors; - ss->preemptors = &preemptor; - - /* Unblock the expected signals */ - blocked = ss->blocked; - ss->blocked &= ~mask; - - _hurd_sigstate_unlock (ss); - - /* Wait. */ - __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - abort (); - } - else - { - assert (signo); - - _hurd_sigstate_lock (ss); - - /* Delete our preemptor. */ - assert (ss->preemptors == &preemptor); - ss->preemptors = preemptor.next; - } - - -all_done: - _hurd_sigstate_unlock (ss); - LIBC_CANCEL_RESET (cancel_oldtype); - - __mach_port_destroy (__mach_task_self (), wait); - *sig = signo; + *sig = ret; return 0; } - libc_hidden_def (__sigwait) weak_alias (__sigwait, sigwait) diff --git a/sysdeps/mach/hurd/sigwaitinfo.c b/sysdeps/mach/hurd/sigwaitinfo.c new file mode 100644 index 0000000000..d70f62328c --- /dev/null +++ b/sysdeps/mach/hurd/sigwaitinfo.c @@ -0,0 +1,28 @@ +/* Implementation of sigwaitinfo function from POSIX.1b. + Copyright (C) 2022 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 + +int +__sigwaitinfo (const sigset_t *set, siginfo_t *info) +{ + return __sigtimedwait (set, info, NULL); +} +libc_hidden_def (__sigwaitinfo) +weak_alias (__sigwaitinfo, sigwaitinfo)