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