]>
Commit | Line | Data |
---|---|---|
efc755b2 | 1 | /* POSIX.1 `sigaction' call for Linux/i386. |
32c075e1 | 2 | Copyright (C) 1991,1995-2000,2002-2004,2005 Free Software Foundation, Inc. |
4cca6b86 | 3 | This file is part of the GNU C Library. |
efc755b2 | 4 | |
4cca6b86 | 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. | |
efc755b2 | 9 | |
4cca6b86 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. |
efc755b2 | 14 | |
41bdb6e2 AJ |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, write to the Free | |
17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
18 | 02111-1307 USA. */ | |
efc755b2 RM |
19 | |
20 | #include <sysdep.h> | |
21 | #include <errno.h> | |
22 | #include <stddef.h> | |
23 | #include <signal.h> | |
ef52edfc | 24 | #include <string.h> |
efc755b2 | 25 | |
adcb550c UD |
26 | #include <sysdep.h> |
27 | #include <sys/syscall.h> | |
8e4f5035 | 28 | #include <ldsodefs.h> |
adcb550c | 29 | |
ea6710d3 UD |
30 | #include <kernel-features.h> |
31 | ||
4cca6b86 UD |
32 | /* The difference here is that the sigaction structure used in the |
33 | kernel is not the same as we use in the libc. Therefore we must | |
34 | translate it here. */ | |
35 | #include <kernel_sigaction.h> | |
36 | ||
25ee8743 UD |
37 | /* We do not globally define the SA_RESTORER flag so do it here. */ |
38 | #define SA_RESTORER 0x04000000 | |
39 | ||
efc755b2 | 40 | |
ea6710d3 | 41 | #if __ASSUME_REALTIME_SIGNALS == 0 |
cbdee279 | 42 | /* The variable is shared between all wrappers around signal handling |
b9b49b44 | 43 | functions which have RT equivalents. */ |
da2d1bc5 | 44 | int __libc_missing_rt_sigs; |
ea6710d3 | 45 | #endif |
cbdee279 | 46 | |
40e15c4d UD |
47 | /* Using the hidden attribute here does not change the code but it |
48 | helps to avoid warnings. */ | |
32c075e1 JJ |
49 | #if defined HAVE_HIDDEN && defined HAVE_VISIBILITY_ATTRIBUTE \ |
50 | && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE | |
51 | # ifdef __NR_rt_sigaction | |
40e15c4d | 52 | extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; |
32c075e1 | 53 | # endif |
78fbd00f | 54 | extern void restore (void) asm ("__restore") attribute_hidden; |
32c075e1 JJ |
55 | #else |
56 | # ifdef __NR_rt_sigaction | |
57 | static void restore_rt (void) asm ("__restore_rt"); | |
58 | # endif | |
59 | static void restore (void) asm ("__restore"); | |
60 | #endif | |
e0082312 | 61 | |
cbdee279 | 62 | |
efc755b2 RM |
63 | /* If ACT is not NULL, change the action for SIG to *ACT. |
64 | If OACT is not NULL, put the old action for SIG in *OACT. */ | |
65 | int | |
c0f53cdd | 66 | __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) |
efc755b2 | 67 | { |
ea6710d3 | 68 | #if __ASSUME_REALTIME_SIGNALS == 0 |
cbdee279 | 69 | struct old_kernel_sigaction k_newact, k_oldact; |
ea6710d3 | 70 | #endif |
efc755b2 RM |
71 | int result; |
72 | ||
655b26bb | 73 | #ifdef __NR_rt_sigaction |
ea6710d3 | 74 | |
cbdee279 | 75 | /* First try the RT signals. */ |
ea6710d3 | 76 | # if __ASSUME_REALTIME_SIGNALS == 0 |
da2d1bc5 | 77 | if (!__libc_missing_rt_sigs) |
ea6710d3 | 78 | # endif |
cbdee279 | 79 | { |
14e9dd67 | 80 | struct kernel_sigaction kact, koact; |
ea6710d3 | 81 | # if __ASSUME_REALTIME_SIGNALS == 0 |
8fb3e007 | 82 | int saved_errno = errno; |
ea6710d3 | 83 | # endif |
cbdee279 | 84 | |
d71b808a UD |
85 | if (act) |
86 | { | |
14e9dd67 | 87 | kact.k_sa_handler = act->sa_handler; |
8e4f5035 | 88 | kact.sa_flags = act->sa_flags; |
14e9dd67 | 89 | memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); |
7cc1894c | 90 | |
afdca0f2 | 91 | if (GLRO(dl_sysinfo_dso) == NULL) |
8e4f5035 UD |
92 | { |
93 | kact.sa_flags |= SA_RESTORER; | |
cbdee279 | 94 | |
8e4f5035 UD |
95 | kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) |
96 | ? &restore_rt : &restore); | |
97 | } | |
d71b808a | 98 | } |
cbdee279 UD |
99 | |
100 | /* XXX The size argument hopefully will have to be changed to the | |
101 | real size of the user-level sigset_t. */ | |
4bbb61e4 GM |
102 | result = INLINE_SYSCALL (rt_sigaction, 4, |
103 | sig, act ? __ptrvalue (&kact) : NULL, | |
104 | oact ? __ptrvalue (&koact) : NULL, _NSIG / 8); | |
cbdee279 | 105 | |
ea6710d3 | 106 | # if __ASSUME_REALTIME_SIGNALS == 0 |
cbdee279 | 107 | if (result >= 0 || errno != ENOSYS) |
ea6710d3 | 108 | # endif |
14e9dd67 UD |
109 | { |
110 | if (oact && result >= 0) | |
111 | { | |
112 | oact->sa_handler = koact.k_sa_handler; | |
113 | memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); | |
114 | oact->sa_flags = koact.sa_flags; | |
115 | oact->sa_restorer = koact.sa_restorer; | |
116 | } | |
117 | return result; | |
118 | } | |
cbdee279 | 119 | |
ea6710d3 | 120 | # if __ASSUME_REALTIME_SIGNALS == 0 |
8fb3e007 | 121 | __set_errno (saved_errno); |
da2d1bc5 | 122 | __libc_missing_rt_sigs = 1; |
ea6710d3 | 123 | # endif |
cbdee279 | 124 | } |
655b26bb | 125 | #endif |
cbdee279 | 126 | |
ea6710d3 | 127 | #if __ASSUME_REALTIME_SIGNALS == 0 |
3e2ee727 | 128 | if (act) |
efc755b2 | 129 | { |
cbdee279 | 130 | k_newact.k_sa_handler = act->sa_handler; |
4cca6b86 | 131 | k_newact.sa_mask = act->sa_mask.__val[0]; |
61bdd24f | 132 | k_newact.sa_flags = act->sa_flags | SA_RESTORER; |
4cca6b86 | 133 | |
e0082312 | 134 | k_newact.sa_restorer = &restore; |
efc755b2 RM |
135 | } |
136 | ||
6aca81bb UD |
137 | result = INLINE_SYSCALL (sigaction, 3, sig, |
138 | act ? __ptrvalue (&k_newact) : 0, | |
139 | oact ? __ptrvalue (&k_oldact) : 0); | |
efc755b2 RM |
140 | |
141 | if (result < 0) | |
6aca81bb | 142 | return -1; |
4cca6b86 UD |
143 | |
144 | if (oact) | |
145 | { | |
cbdee279 | 146 | oact->sa_handler = k_oldact.k_sa_handler; |
4cca6b86 UD |
147 | oact->sa_mask.__val[0] = k_oldact.sa_mask; |
148 | oact->sa_flags = k_oldact.sa_flags; | |
149 | oact->sa_restorer = k_oldact.sa_restorer; | |
150 | } | |
151 | ||
efc755b2 | 152 | return 0; |
ea6710d3 | 153 | #endif |
efc755b2 | 154 | } |
5ec5c857 | 155 | libc_hidden_def (__libc_sigaction) |
efc755b2 | 156 | |
8b4f1598 UD |
157 | #ifdef WRAPPER_INCLUDE |
158 | # include WRAPPER_INCLUDE | |
159 | #endif | |
160 | ||
bf293afe | 161 | #ifndef LIBC_SIGACTION |
ab18b1e1 | 162 | weak_alias (__libc_sigaction, __sigaction) |
37ba7d66 | 163 | libc_hidden_weak (__sigaction) |
c0f53cdd | 164 | weak_alias (__libc_sigaction, sigaction) |
ace55c73 | 165 | #endif |
e0082312 | 166 | |
adcf0e4a UD |
167 | /* NOTE: Please think twice before making any changes to the bits of |
168 | code below. GDB needs some intimate knowledge about it to | |
169 | recognize them as signal trampolines, and make backtraces through | |
170 | signal handlers work right. Important are both the names | |
171 | (__restore and __restore_rt) and the exact instruction sequence. | |
172 | If you ever feel the need to make any changes, please notify the | |
173 | appropriate GDB maintainer. */ | |
174 | ||
8e4f5035 UD |
175 | #define RESTORE(name, syscall) RESTORE2 (name, syscall) |
176 | #define RESTORE2(name, syscall) \ | |
e0082312 UD |
177 | asm \ |
178 | ( \ | |
4dbb6417 UD |
179 | ".text\n" \ |
180 | " .align 16\n" \ | |
adcf0e4a | 181 | "__" #name ":\n" \ |
e0082312 UD |
182 | " movl $" #syscall ", %eax\n" \ |
183 | " int $0x80" \ | |
184 | ); | |
185 | ||
8e4f5035 | 186 | #ifdef __NR_rt_sigaction |
e0082312 UD |
187 | /* The return code for realtime-signals. */ |
188 | RESTORE (restore_rt, __NR_rt_sigreturn) | |
8e4f5035 | 189 | #endif |
e0082312 UD |
190 | |
191 | /* For the boring old signals. */ | |
8e4f5035 UD |
192 | #undef RESTORE2 |
193 | #define RESTORE2(name, syscall) \ | |
e0082312 UD |
194 | asm \ |
195 | ( \ | |
4dbb6417 UD |
196 | ".text\n" \ |
197 | " .align 8\n" \ | |
adcf0e4a | 198 | "__" #name ":\n" \ |
e0082312 UD |
199 | " popl %eax\n" \ |
200 | " movl $" #syscall ", %eax\n" \ | |
201 | " int $0x80" \ | |
202 | ); | |
203 | ||
204 | RESTORE (restore, __NR_sigreturn) |