]>
Commit | Line | Data |
---|---|---|
efc755b2 | 1 | /* POSIX.1 `sigaction' call for Linux/i386. |
688903eb | 2 | Copyright (C) 1991-2018 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 | 15 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
efc755b2 RM |
18 | |
19 | #include <sysdep.h> | |
20 | #include <errno.h> | |
21 | #include <stddef.h> | |
22 | #include <signal.h> | |
ef52edfc | 23 | #include <string.h> |
efc755b2 | 24 | |
adcb550c UD |
25 | #include <sysdep.h> |
26 | #include <sys/syscall.h> | |
8e4f5035 | 27 | #include <ldsodefs.h> |
adcb550c | 28 | |
4cca6b86 UD |
29 | /* The difference here is that the sigaction structure used in the |
30 | kernel is not the same as we use in the libc. Therefore we must | |
31 | translate it here. */ | |
32 | #include <kernel_sigaction.h> | |
33 | ||
25ee8743 UD |
34 | /* We do not globally define the SA_RESTORER flag so do it here. */ |
35 | #define SA_RESTORER 0x04000000 | |
36 | ||
efc755b2 | 37 | |
40e15c4d UD |
38 | /* Using the hidden attribute here does not change the code but it |
39 | helps to avoid warnings. */ | |
11bf311e | 40 | #ifdef __NR_rt_sigaction |
40e15c4d | 41 | extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; |
32c075e1 | 42 | #endif |
11bf311e | 43 | extern void restore (void) asm ("__restore") attribute_hidden; |
e0082312 | 44 | |
cbdee279 | 45 | |
efc755b2 RM |
46 | /* If ACT is not NULL, change the action for SIG to *ACT. |
47 | If OACT is not NULL, put the old action for SIG in *OACT. */ | |
48 | int | |
c0f53cdd | 49 | __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) |
efc755b2 | 50 | { |
efc755b2 RM |
51 | int result; |
52 | ||
ffb7875d | 53 | struct kernel_sigaction kact, koact; |
ea6710d3 | 54 | |
ffb7875d | 55 | if (act) |
cbdee279 | 56 | { |
ffb7875d JM |
57 | kact.k_sa_handler = act->sa_handler; |
58 | kact.sa_flags = act->sa_flags; | |
59 | memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); | |
cbdee279 | 60 | |
ffb7875d | 61 | if (GLRO(dl_sysinfo_dso) == NULL) |
d71b808a | 62 | { |
ffb7875d | 63 | kact.sa_flags |= SA_RESTORER; |
7cc1894c | 64 | |
ffb7875d JM |
65 | kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) |
66 | ? &restore_rt : &restore); | |
14e9dd67 | 67 | } |
efc755b2 RM |
68 | } |
69 | ||
ffb7875d JM |
70 | /* XXX The size argument hopefully will have to be changed to the |
71 | real size of the user-level sigset_t. */ | |
8f763b04 L |
72 | INTERNAL_SYSCALL_DECL (err); |
73 | result = INTERNAL_SYSCALL (rt_sigaction, err, 4, | |
74 | sig, act ? &kact : NULL, | |
75 | oact ? &koact : NULL, _NSIG / 8); | |
76 | if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) | |
751709fe AS |
77 | return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (result, |
78 | err)); | |
8f763b04 | 79 | else if (oact && result >= 0) |
4cca6b86 | 80 | { |
ffb7875d JM |
81 | oact->sa_handler = koact.k_sa_handler; |
82 | memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); | |
83 | oact->sa_flags = koact.sa_flags; | |
84 | oact->sa_restorer = koact.sa_restorer; | |
4cca6b86 | 85 | } |
ffb7875d | 86 | return result; |
efc755b2 | 87 | } |
5ec5c857 | 88 | libc_hidden_def (__libc_sigaction) |
efc755b2 | 89 | |
08192659 | 90 | #include <nptl/sigaction.c> |
e0082312 | 91 | |
adcf0e4a UD |
92 | /* NOTE: Please think twice before making any changes to the bits of |
93 | code below. GDB needs some intimate knowledge about it to | |
94 | recognize them as signal trampolines, and make backtraces through | |
95 | signal handlers work right. Important are both the names | |
96 | (__restore and __restore_rt) and the exact instruction sequence. | |
97 | If you ever feel the need to make any changes, please notify the | |
98 | appropriate GDB maintainer. */ | |
99 | ||
8e4f5035 UD |
100 | #define RESTORE(name, syscall) RESTORE2 (name, syscall) |
101 | #define RESTORE2(name, syscall) \ | |
e0082312 UD |
102 | asm \ |
103 | ( \ | |
4dbb6417 UD |
104 | ".text\n" \ |
105 | " .align 16\n" \ | |
adcf0e4a | 106 | "__" #name ":\n" \ |
e0082312 UD |
107 | " movl $" #syscall ", %eax\n" \ |
108 | " int $0x80" \ | |
109 | ); | |
110 | ||
8e4f5035 | 111 | #ifdef __NR_rt_sigaction |
e0082312 UD |
112 | /* The return code for realtime-signals. */ |
113 | RESTORE (restore_rt, __NR_rt_sigreturn) | |
8e4f5035 | 114 | #endif |
e0082312 UD |
115 | |
116 | /* For the boring old signals. */ | |
8e4f5035 UD |
117 | #undef RESTORE2 |
118 | #define RESTORE2(name, syscall) \ | |
e0082312 UD |
119 | asm \ |
120 | ( \ | |
4dbb6417 UD |
121 | ".text\n" \ |
122 | " .align 8\n" \ | |
adcf0e4a | 123 | "__" #name ":\n" \ |
e0082312 UD |
124 | " popl %eax\n" \ |
125 | " movl $" #syscall ", %eax\n" \ | |
126 | " int $0x80" \ | |
127 | ); | |
128 | ||
129 | RESTORE (restore, __NR_sigreturn) |