From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1792) id 11DDA3858C33; Mon, 7 Nov 2022 20:16:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 11DDA3858C33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1667852197; bh=yy4Q2iYz8AtDWRUeJtBGlPpr6IAtAJNh2Nlu1rIz56U=; h=From:To:Subject:Date:From; b=qXm/RBAgAXch/xiKr1W4IKpGb7jNcZuLuHO6O6oXslicLRFLQhPkDV2lBcaaQqhCk q0zGxY5qAhwBMGVr452wNCjcEQUTFX6qiTnvtO0ubRT9AIIOI7g7bCPWCbOevXjJlt oxDOOquVdQ0WQyyhLMaMUN4nikalhg4lGz/VchP4= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Samuel Thibault To: glibc-cvs@sourceware.org Subject: [glibc] hurd: Add sigtimedwait and sigwaitinfo support X-Act-Checkin: glibc X-Git-Author: Samuel Thibault X-Git-Refname: refs/heads/master X-Git-Oldrev: 8d291eabd541029d7ac705cc1ea112c58dfbb05f X-Git-Newrev: 19934d629ee22bbd332f04da4320e4f624c9560c Message-Id: <20221107201637.11DDA3858C33@sourceware.org> Date: Mon, 7 Nov 2022 20:16:37 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=19934d629ee22bbd332f04da4320e4f624c9560c commit 19934d629ee22bbd332f04da4320e4f624c9560c Author: Samuel Thibault Date: Mon Nov 7 21:14:39 2022 +0100 hurd: Add sigtimedwait and sigwaitinfo support This simply needed to add the timeout parameter to mach_msg, and copy information from struct hurd_signal_detail. Diff: --- 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(-) 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)