1 /* Copyright (C) 1991-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #include <errno.h>
19 #include <signal.h>
20 #include <hurd.h>
21 #include <hurd/signal.h>
22 #include <hurd/msg.h>
23 
24 /* If SET is not NULL, modify the current set of blocked signals
25    according to HOW, which may be SIG_BLOCK, SIG_UNBLOCK or SIG_SETMASK.
26    If OSET is not NULL, store the old set of blocked signals in *OSET.  */
27 int
__sigprocmask(int how,const sigset_t * set,sigset_t * oset)28 __sigprocmask (int how, const sigset_t *set, sigset_t *oset)
29 {
30   struct hurd_sigstate *ss;
31   sigset_t old, new;
32   sigset_t pending;
33 
34   if (set != NULL)
35     new = *set;
36 
37   ss = _hurd_self_sigstate ();
38 
39   _hurd_sigstate_lock (ss);
40 
41   old = ss->blocked;
42 
43   if (set != NULL)
44     {
45       switch (how)
46 	{
47 	case SIG_BLOCK:
48 	  __sigorset (&ss->blocked, &ss->blocked, &new);
49 	  break;
50 
51 	case SIG_UNBLOCK:
52 	  ss->blocked &= ~new;
53 	  break;
54 
55 	case SIG_SETMASK:
56 	  ss->blocked = new;
57 	  break;
58 
59 	default:
60 	  _hurd_sigstate_unlock (ss);
61 	  errno = EINVAL;
62 	  return -1;
63 	}
64 
65       ss->blocked &= ~_SIG_CANT_MASK;
66     }
67 
68   pending = _hurd_sigstate_pending (ss) & ~ss->blocked;
69 
70   _hurd_sigstate_unlock (ss);
71 
72   if (oset != NULL)
73     *oset = old;
74 
75   if (pending)
76     /* Send a message to the signal thread so it
77        will wake up and check for pending signals.  */
78     __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
79 
80   return 0;
81 }
82 
83 libc_hidden_def (__sigprocmask)
84 weak_alias (__sigprocmask, sigprocmask)
85