]>
Commit | Line | Data |
---|---|---|
b168057a | 1 | /* Copyright (C) 1997-2015 Free Software Foundation, Inc. |
462d695a UD |
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 | |
3214b89b AJ |
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. | |
462d695a UD |
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 | |
3214b89b | 12 | Lesser General Public License for more details. |
462d695a | 13 | |
3214b89b | 14 | You should have received a copy of the GNU Lesser General Public |
ab84e3ff PE |
15 | License along with the GNU C Library. If not, see |
16 | <http://www.gnu.org/licenses/>. */ | |
462d695a UD |
17 | |
18 | #include <errno.h> | |
19 | #include <signal.h> | |
20 | #include <string.h> | |
21 | ||
22 | #include <sysdep.h> | |
23 | #include <sys/syscall.h> | |
24 | ||
25 | /* The difference here is that the sigaction structure used in the | |
26 | kernel is not the same as we use in the libc. Therefore we must | |
27 | translate it here. */ | |
28 | #include <kernel_sigaction.h> | |
29 | ||
462d695a UD |
30 | #define SA_RESTORER 0x04000000 |
31 | ||
2272ffc1 JM |
32 | extern void __default_sa_restorer (void); |
33 | extern void __default_rt_sa_restorer (void); | |
2761e5ac | 34 | |
462d695a | 35 | /* When RT signals are in use we need to use a different return stub. */ |
462d695a | 36 | #define choose_restorer(flags) \ |
2761e5ac UD |
37 | (flags & SA_SIGINFO) ? __default_rt_sa_restorer \ |
38 | : __default_sa_restorer | |
462d695a UD |
39 | |
40 | /* If ACT is not NULL, change the action for SIG to *ACT. | |
41 | If OACT is not NULL, put the old action for SIG in *OACT. */ | |
42 | int | |
bd2260a2 | 43 | __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) |
462d695a | 44 | { |
462d695a UD |
45 | int result; |
46 | ||
c5754569 | 47 | struct kernel_sigaction kact, koact; |
462d695a UD |
48 | |
49 | if (act) | |
50 | { | |
c5754569 JM |
51 | kact.k_sa_handler = act->sa_handler; |
52 | memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); | |
53 | kact.sa_flags = act->sa_flags; | |
54 | #ifdef HAVE_SA_RESTORER | |
55 | if (kact.sa_flags & SA_RESTORER) | |
56 | kact.sa_restorer = act->sa_restorer; | |
462d695a UD |
57 | else |
58 | { | |
c5754569 JM |
59 | kact.sa_restorer = choose_restorer (kact.sa_flags); |
60 | kact.sa_flags |= SA_RESTORER; | |
462d695a | 61 | } |
c5754569 | 62 | #endif |
462d695a | 63 | } |
c5754569 JM |
64 | |
65 | /* XXX The size argument hopefully will have to be changed to the | |
66 | real size of the user-level sigset_t. */ | |
67 | result = INLINE_SYSCALL (rt_sigaction, 4, sig, | |
70d9946a JM |
68 | act ? &kact : NULL, |
69 | oact ? &koact : NULL, _NSIG / 8); | |
c5754569 | 70 | |
462d695a UD |
71 | if (oact && result >= 0) |
72 | { | |
c5754569 JM |
73 | oact->sa_handler = koact.k_sa_handler; |
74 | memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); | |
75 | oact->sa_flags = koact.sa_flags; | |
76 | #ifdef HAVE_SA_RESTORER | |
77 | oact->sa_restorer = koact.sa_restorer; | |
78 | #endif | |
462d695a UD |
79 | } |
80 | return result; | |
462d695a | 81 | } |
c5947147 | 82 | libc_hidden_def (__libc_sigaction) |
eb22472e | 83 | |
08192659 | 84 | #include <nptl/sigaction.c> |