]>
Commit | Line | Data |
---|---|---|
44422d11 RM |
1 | /* Copyright (C) 1997,1998,1999,2000,2002,2003,2004,2006 |
2 | Free Software Foundation, Inc. | |
f0fe91e7 AJ |
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. | |
f0fe91e7 AJ |
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 | |
3214b89b AJ |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. | |
f0fe91e7 | 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/>. */ | |
f0fe91e7 AJ |
18 | |
19 | #include <errno.h> | |
b8ddf7a1 | 20 | #include <sgidefs.h> |
f0fe91e7 AJ |
21 | #include <signal.h> |
22 | #include <string.h> | |
23 | ||
24 | #include <sysdep.h> | |
25 | #include <sys/syscall.h> | |
26 | ||
24c4c341 AJ |
27 | #include <sgidefs.h> |
28 | ||
44422d11 | 29 | #include <kernel-features.h> |
f0fe91e7 AJ |
30 | |
31 | /* The difference here is that the sigaction structure used in the | |
32 | kernel is not the same as we use in the libc. Therefore we must | |
33 | translate it here. */ | |
34 | #include <kernel_sigaction.h> | |
35 | ||
36 | #if __ASSUME_REALTIME_SIGNALS == 0 | |
37 | /* The variable is shared between all wrappers around signal handling | |
38 | functions which have RT equivalents. This is the definition. */ | |
39 | int __libc_missing_rt_sigs; | |
40 | ||
f0fe91e7 | 41 | #endif |
f0fe91e7 | 42 | |
b8ddf7a1 | 43 | #if _MIPS_SIM != _ABIO32 |
ab35974e AO |
44 | |
45 | # ifdef __NR_rt_sigreturn | |
46 | static void restore_rt (void) asm ("__restore_rt"); | |
47 | # endif | |
48 | # ifdef __NR_sigreturn | |
49 | static void restore (void) asm ("__restore"); | |
50 | # endif | |
51 | #endif | |
f0fe91e7 AJ |
52 | |
53 | /* If ACT is not NULL, change the action for SIG to *ACT. | |
54 | If OACT is not NULL, put the old action for SIG in *OACT. */ | |
55 | int | |
56 | __libc_sigaction (sig, act, oact) | |
57 | int sig; | |
58 | const struct sigaction *act; | |
59 | struct sigaction *oact; | |
60 | { | |
61 | #if __ASSUME_REALTIME_SIGNALS == 0 | |
62 | struct old_kernel_sigaction k_sigact, k_osigact; | |
63 | #endif | |
64 | int result; | |
65 | ||
66 | #if defined __NR_rt_sigaction || __ASSUME_REALTIME_SIGNALS > 0 | |
67 | /* First try the RT signals. */ | |
68 | # if __ASSUME_REALTIME_SIGNALS == 0 | |
69 | if (!__libc_missing_rt_sigs) | |
70 | # endif | |
71 | { | |
72 | struct kernel_sigaction kact, koact; | |
73 | /* Save the current error value for later. We need not do this | |
74 | if we are guaranteed to have realtime signals. */ | |
75 | # if __ASSUME_REALTIME_SIGNALS == 0 | |
76 | int saved_errno = errno; | |
77 | # endif | |
78 | ||
79 | if (act) | |
80 | { | |
81 | kact.k_sa_handler = act->sa_handler; | |
82 | memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kernel_sigset_t)); | |
83 | kact.sa_flags = act->sa_flags; | |
84 | # ifdef HAVE_SA_RESTORER | |
b8ddf7a1 | 85 | # if _MIPS_SIM == _ABIO32 |
f0fe91e7 | 86 | kact.sa_restorer = act->sa_restorer; |
ab35974e AO |
87 | # else |
88 | kact.sa_restorer = &restore_rt; | |
89 | # endif | |
f0fe91e7 AJ |
90 | # endif |
91 | } | |
92 | ||
93 | /* XXX The size argument hopefully will have to be changed to the | |
94 | real size of the user-level sigset_t. */ | |
95 | result = INLINE_SYSCALL (rt_sigaction, 4, sig, | |
96 | act ? __ptrvalue (&kact) : NULL, | |
97 | oact ? __ptrvalue (&koact) : NULL, | |
98 | sizeof (kernel_sigset_t)); | |
99 | ||
100 | # if __ASSUME_REALTIME_SIGNALS == 0 | |
101 | if (result >= 0 || errno != ENOSYS) | |
102 | # endif | |
103 | { | |
104 | if (oact && result >= 0) | |
105 | { | |
106 | oact->sa_handler = koact.k_sa_handler; | |
107 | memcpy (&oact->sa_mask, &koact.sa_mask, | |
108 | sizeof (kernel_sigset_t)); | |
109 | oact->sa_flags = koact.sa_flags; | |
110 | # ifdef HAVE_SA_RESTORER | |
111 | oact->sa_restorer = koact.sa_restorer; | |
112 | # endif | |
113 | } | |
114 | return result; | |
115 | } | |
116 | ||
117 | # if __ASSUME_REALTIME_SIGNALS == 0 | |
118 | __set_errno (saved_errno); | |
119 | __libc_missing_rt_sigs = 1; | |
120 | # endif | |
121 | } | |
122 | #endif | |
123 | ||
124 | #if __ASSUME_REALTIME_SIGNALS == 0 | |
125 | if (act) | |
126 | { | |
127 | k_sigact.k_sa_handler = act->sa_handler; | |
128 | k_sigact.sa_mask = act->sa_mask.__val[0]; | |
129 | k_sigact.sa_flags = act->sa_flags; | |
130 | # ifdef HAVE_SA_RESTORER | |
131 | k_sigact.sa_restorer = act->sa_restorer; | |
132 | # endif | |
133 | } | |
134 | result = INLINE_SYSCALL (sigaction, 3, sig, | |
135 | act ? __ptrvalue (&k_sigact) : NULL, | |
136 | oact ? __ptrvalue (&k_osigact) : NULL); | |
137 | if (oact && result >= 0) | |
138 | { | |
139 | oact->sa_handler = k_osigact.k_sa_handler; | |
140 | oact->sa_mask.__val[0] = k_osigact.sa_mask; | |
141 | oact->sa_flags = k_osigact.sa_flags; | |
142 | # ifdef HAVE_SA_RESTORER | |
b8ddf7a1 | 143 | # if _MIPS_SIM == _ABIO32 |
f0fe91e7 | 144 | oact->sa_restorer = k_osigact.sa_restorer; |
ab35974e AO |
145 | # else |
146 | oact->sa_restorer = &restore; | |
147 | # endif | |
f0fe91e7 AJ |
148 | # endif |
149 | } | |
150 | return result; | |
151 | #endif | |
152 | } | |
c5947147 | 153 | libc_hidden_def (__libc_sigaction) |
eb22472e | 154 | |
bb600a60 DJ |
155 | #ifdef WRAPPER_INCLUDE |
156 | # include WRAPPER_INCLUDE | |
157 | #endif | |
158 | ||
eb22472e | 159 | #ifndef LIBC_SIGACTION |
f0fe91e7 | 160 | weak_alias (__libc_sigaction, __sigaction) |
da5f5f79 | 161 | libc_hidden_weak (__sigaction) |
f0fe91e7 | 162 | weak_alias (__libc_sigaction, sigaction) |
eb22472e | 163 | #endif |
ab35974e AO |
164 | |
165 | /* NOTE: Please think twice before making any changes to the bits of | |
166 | code below. GDB needs some intimate knowledge about it to | |
167 | recognize them as signal trampolines, and make backtraces through | |
168 | signal handlers work right. Important are both the names | |
169 | (__restore_rt) and the exact instruction sequence. | |
170 | If you ever feel the need to make any changes, please notify the | |
171 | appropriate GDB maintainer. */ | |
172 | ||
173 | #define RESTORE(name, syscall) RESTORE2 (name, syscall) | |
174 | #define RESTORE2(name, syscall) \ | |
175 | asm \ | |
176 | ( \ | |
177 | ".align 4\n" \ | |
178 | "__" #name ":\n" \ | |
179 | " li $2, " #syscall "\n" \ | |
180 | " syscall\n" \ | |
181 | ); | |
182 | ||
183 | /* The return code for realtime-signals. */ | |
b8ddf7a1 | 184 | #if _MIPS_SIM != _ABIO32 |
ab35974e AO |
185 | # ifdef __NR_rt_sigreturn |
186 | RESTORE (restore_rt, __NR_rt_sigreturn) | |
187 | # endif | |
188 | # ifdef __NR_sigreturn | |
189 | RESTORE (restore, __NR_sigreturn) | |
190 | # endif | |
191 | #endif |