]>
Commit | Line | Data |
---|---|---|
f4151d89 | 1 | /* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2005, 2006 |
02a9f771 | 2 | Free Software Foundation, Inc. |
462d695a UD |
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 | |
3214b89b 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. | |
462d695a UD |
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 | |
3214b89b | 13 | Lesser General Public License for more details. |
462d695a | 14 | |
3214b89b | 15 | You should have received a copy of the GNU Lesser General Public |
ab84e3ff PE |
16 | License along with the GNU C Library. If not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
462d695a UD |
18 | |
19 | #include <errno.h> | |
20 | #include <signal.h> | |
21 | #include <string.h> | |
22 | ||
23 | #include <sysdep.h> | |
24 | #include <sys/syscall.h> | |
227de9dd | 25 | #include <kernel-features.h> |
462d695a UD |
26 | |
27 | /* The difference here is that the sigaction structure used in the | |
28 | kernel is not the same as we use in the libc. Therefore we must | |
29 | translate it here. */ | |
30 | #include <kernel_sigaction.h> | |
31 | ||
462d695a UD |
32 | /* The variable is shared between all wrappers around signal handling |
33 | functions which have RT equivalents. */ | |
34 | int __libc_missing_rt_sigs; | |
35 | ||
36 | #define SA_RESTORER 0x04000000 | |
37 | ||
99e5e16c DJ |
38 | #ifdef __ARM_EABI__ |
39 | extern void __default_sa_restorer_v1(void); | |
40 | extern void __default_sa_restorer_v2(void); | |
41 | extern void __default_rt_sa_restorer_v1(void); | |
42 | extern void __default_rt_sa_restorer_v2(void); | |
43 | # ifdef __ASSUME_SIGFRAME_V2 | |
44 | # define __default_sa_restorer __default_sa_restorer_v2 | |
45 | # define __default_rt_sa_restorer __default_rt_sa_restorer_v2 | |
46 | # else | |
47 | # include <ldsodefs.h> | |
48 | # define __default_sa_restorer (GLRO(dl_osversion) >= 0x020612 \ | |
49 | ? __default_sa_restorer_v2 \ | |
50 | : __default_sa_restorer_v1) | |
51 | # define __default_rt_sa_restorer (GLRO(dl_osversion) >= 0x020612 \ | |
52 | ? __default_rt_sa_restorer_v2 \ | |
53 | : __default_rt_sa_restorer_v1) | |
54 | # endif | |
55 | #else | |
2761e5ac UD |
56 | extern void __default_sa_restorer(void); |
57 | extern void __default_rt_sa_restorer(void); | |
99e5e16c | 58 | #endif |
2761e5ac | 59 | |
462d695a UD |
60 | /* When RT signals are in use we need to use a different return stub. */ |
61 | #ifdef __NR_rt_sigreturn | |
62 | #define choose_restorer(flags) \ | |
2761e5ac UD |
63 | (flags & SA_SIGINFO) ? __default_rt_sa_restorer \ |
64 | : __default_sa_restorer | |
462d695a UD |
65 | #else |
66 | #define choose_restorer(flags) \ | |
5f406da8 | 67 | __default_sa_restorer |
462d695a UD |
68 | #endif |
69 | ||
70 | /* If ACT is not NULL, change the action for SIG to *ACT. | |
71 | If OACT is not NULL, put the old action for SIG in *OACT. */ | |
72 | int | |
71005584 | 73 | __libc_sigaction (sig, act, oact) |
462d695a UD |
74 | int sig; |
75 | const struct sigaction *act; | |
76 | struct sigaction *oact; | |
77 | { | |
227de9dd | 78 | #ifndef __ASSUME_REALTIME_SIGNALS |
462d695a | 79 | struct old_kernel_sigaction k_sigact, k_osigact; |
227de9dd | 80 | #endif |
462d695a UD |
81 | int result; |
82 | ||
83 | #ifdef __NR_rt_sigaction | |
84 | /* First try the RT signals. */ | |
227de9dd | 85 | # ifndef __ASSUME_REALTIME_SIGNALS |
462d695a | 86 | if (!__libc_missing_rt_sigs) |
227de9dd | 87 | # endif |
462d695a UD |
88 | { |
89 | struct kernel_sigaction kact, koact; | |
227de9dd | 90 | # ifndef __ASSUME_REALTIME_SIGNALS |
462d695a | 91 | int saved_errno = errno; |
227de9dd | 92 | # endif |
462d695a UD |
93 | |
94 | if (act) | |
95 | { | |
96 | kact.k_sa_handler = act->sa_handler; | |
97 | memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); | |
98 | kact.sa_flags = act->sa_flags; | |
99 | # ifdef HAVE_SA_RESTORER | |
02a9f771 | 100 | if (kact.sa_flags & SA_RESTORER) |
462d695a UD |
101 | kact.sa_restorer = act->sa_restorer; |
102 | else | |
103 | { | |
104 | kact.sa_restorer = choose_restorer (kact.sa_flags); | |
105 | kact.sa_flags |= SA_RESTORER; | |
106 | } | |
107 | # endif | |
108 | } | |
109 | ||
110 | /* XXX The size argument hopefully will have to be changed to the | |
111 | real size of the user-level sigset_t. */ | |
e3d6c581 GM |
112 | result = INLINE_SYSCALL (rt_sigaction, 4, sig, |
113 | act ? __ptrvalue (&kact) : NULL, | |
114 | oact ? __ptrvalue (&koact) : NULL, _NSIG / 8); | |
462d695a | 115 | |
227de9dd | 116 | # ifndef __ASSUME_REALTIME_SIGNALS |
462d695a | 117 | if (result >= 0 || errno != ENOSYS) |
227de9dd | 118 | # endif |
462d695a UD |
119 | { |
120 | if (oact && result >= 0) | |
121 | { | |
122 | oact->sa_handler = koact.k_sa_handler; | |
123 | memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); | |
124 | oact->sa_flags = koact.sa_flags; | |
125 | # ifdef HAVE_SA_RESTORER | |
126 | oact->sa_restorer = koact.sa_restorer; | |
127 | # endif | |
128 | } | |
129 | return result; | |
130 | } | |
131 | ||
227de9dd | 132 | # ifndef __ASSUME_REALTIME_SIGNALS |
462d695a UD |
133 | __set_errno (saved_errno); |
134 | __libc_missing_rt_sigs = 1; | |
227de9dd | 135 | # endif |
462d695a UD |
136 | } |
137 | #endif | |
138 | ||
227de9dd | 139 | #ifndef __ASSUME_REALTIME_SIGNALS |
462d695a UD |
140 | if (act) |
141 | { | |
142 | k_sigact.k_sa_handler = act->sa_handler; | |
143 | k_sigact.sa_mask = act->sa_mask.__val[0]; | |
144 | k_sigact.sa_flags = act->sa_flags; | |
227de9dd | 145 | # ifdef HAVE_SA_RESTORER |
02a9f771 | 146 | if (k_sigact.sa_flags & SA_RESTORER) |
462d695a UD |
147 | k_sigact.sa_restorer = act->sa_restorer; |
148 | else | |
149 | { | |
150 | k_sigact.sa_restorer = choose_restorer (k_sigact.sa_flags); | |
151 | k_sigact.sa_flags |= SA_RESTORER; | |
152 | } | |
227de9dd | 153 | # endif |
462d695a | 154 | } |
e3d6c581 GM |
155 | result = INLINE_SYSCALL (sigaction, 3, sig, |
156 | act ? __ptrvalue (&k_sigact) : NULL, | |
157 | oact ? __ptrvalue (&k_osigact) : NULL); | |
462d695a UD |
158 | if (oact && result >= 0) |
159 | { | |
160 | oact->sa_handler = k_osigact.k_sa_handler; | |
161 | oact->sa_mask.__val[0] = k_osigact.sa_mask; | |
162 | oact->sa_flags = k_osigact.sa_flags; | |
227de9dd | 163 | # ifdef HAVE_SA_RESTORER |
462d695a | 164 | oact->sa_restorer = k_osigact.sa_restorer; |
227de9dd | 165 | # endif |
462d695a UD |
166 | } |
167 | return result; | |
227de9dd | 168 | #endif |
462d695a | 169 | } |
c5947147 | 170 | libc_hidden_def (__libc_sigaction) |
eb22472e | 171 | |
f4151d89 DJ |
172 | #ifdef WRAPPER_INCLUDE |
173 | # include WRAPPER_INCLUDE | |
174 | #endif | |
175 | ||
eb22472e | 176 | #ifndef LIBC_SIGACTION |
cc5d8c39 | 177 | weak_alias (__libc_sigaction, __sigaction) |
da5f5f79 | 178 | libc_hidden_weak (__sigaction) |
71005584 | 179 | weak_alias (__libc_sigaction, sigaction) |
eb22472e | 180 | #endif |