]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/mach/hurd/sigaction.c
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / sysdeps / mach / hurd / sigaction.c
CommitLineData
04277e02 1/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
3dadfa7e 2
ebbad4cc 3 This file is part of the GNU C Library.
28f540f4 4
ebbad4cc 5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
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.
28f540f4 9
ebbad4cc
UD
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
41bdb6e2 13 Lesser General Public License for more details.
28f540f4 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
28f540f4 18
28f540f4
RM
19#include <errno.h>
20#include <signal.h>
21#include <hurd.h>
22#include <hurd/signal.h>
23
24/* If ACT is not NULL, change the action for SIG to *ACT.
25 If OACT is not NULL, put the old action for SIG in *OACT. */
26int
bd2260a2 27__sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
28f540f4
RM
28{
29 struct hurd_sigstate *ss;
30 struct sigaction a, old;
31 sigset_t pending;
32
c5f65462
JM
33 if (sig <= 0 || sig >= NSIG
34 || (act != NULL && act->sa_handler != SIG_DFL
35 && ((__sigmask (sig) & _SIG_CANT_MASK)
36 || act->sa_handler == SIG_ERR)))
28f540f4
RM
37 {
38 errno = EINVAL;
39 return -1;
40 }
41
42 /* Copy so we fault before taking locks. */
43 if (act != NULL)
44 a = *act;
45
46 ss = _hurd_self_sigstate ();
47
8f0c527e 48 __spin_lock (&ss->critical_section_lock);
28f540f4
RM
49 __spin_lock (&ss->lock);
50 old = ss->actions[sig];
51 if (act != NULL)
52 ss->actions[sig] = a;
53
c5f65462
JM
54 if (act != NULL && sig == SIGCHLD
55 && (a.sa_flags & SA_NOCLDSTOP) != (old.sa_flags & SA_NOCLDSTOP))
28f540f4 56 {
28f540f4
RM
57 __spin_unlock (&ss->lock);
58
59 /* Inform the proc server whether or not it should send us SIGCHLD for
60 stopped children. We do this in a critical section so that no
61 SIGCHLD can arrive in the middle and be of indeterminate status. */
62 __USEPORT (PROC,
63 __proc_mod_stopchild (port, !(a.sa_flags & SA_NOCLDSTOP)));
64
65 __spin_lock (&ss->lock);
28f540f4
RM
66 pending = ss->pending & ~ss->blocked;
67 }
610903b0 68 else if (act != NULL && (a.sa_handler == SIG_IGN || a.sa_handler == SIG_DFL))
4d02a5b1
RM
69 /* We are changing to an action that might be to ignore SIG signals.
70 If SIG is blocked and pending and the new action is to ignore it, we
71 must remove it from the pending set now; if the action is changed
72 back and then SIG is unblocked, the signal pending now should not
73 arrive. So wake up the signal thread to check the new state and do
74 the right thing. */
75 pending = ss->pending & __sigmask (sig);
28f540f4
RM
76 else
77 pending = 0;
78
79 __spin_unlock (&ss->lock);
8f0c527e 80 __spin_unlock (&ss->critical_section_lock);
28f540f4
RM
81
82 if (pending)
8f0c527e 83 __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
28f540f4
RM
84
85 if (oact != NULL)
86 *oact = old;
87
88 return 0;
89}
37ba7d66 90libc_hidden_def (__sigaction)
28f540f4 91weak_alias (__sigaction, sigaction)