f7ff4a6198b302232a83a883c860953142fd438e
[musl] / src / signal / sigaction.c
1 #include <signal.h>
2 #include <errno.h>
3 #include <string.h>
4 #include "syscall.h"
5 #include "pthread_impl.h"
6 #include "libc.h"
7 #include "ksigaction.h"
8
9 void __restore(), __restore_rt();
10
11 static pthread_t dummy(void) { return 0; }
12 weak_alias(dummy, __pthread_self_def);
13
14 static unsigned long handler_set[_NSIG/(8*sizeof(long))];
15
16 void __get_handler_set(sigset_t *set)
17 {
18         memcpy(set, handler_set, sizeof handler_set);
19 }
20
21 int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
22 {
23         struct k_sigaction ksa, ksa_old;
24         if (sig >= (unsigned)_NSIG) {
25                 errno = EINVAL;
26                 return -1;
27         }
28         if (sa) {
29                 if ((uintptr_t)sa->sa_handler > 1UL) {
30                         a_or_l(handler_set+(sig-1)/(8*sizeof(long)),
31                                 1UL<<(sig-1)%(8*sizeof(long)));
32                         __pthread_self_def();
33                 }
34                 ksa.handler = sa->sa_handler;
35                 ksa.flags = sa->sa_flags | SA_RESTORER;
36                 ksa.restorer = (sa->sa_flags & SA_SIGINFO) ? __restore_rt : __restore;
37                 memcpy(&ksa.mask, &sa->sa_mask, sizeof ksa.mask);
38         }
39         if (syscall(SYS_rt_sigaction, sig, sa?&ksa:0, old?&ksa_old:0, sizeof ksa.mask))
40                 return -1;
41         if (old) {
42                 old->sa_handler = ksa_old.handler;
43                 old->sa_flags = ksa_old.flags;
44                 memcpy(&old->sa_mask, &ksa_old.mask, sizeof ksa_old.mask);
45         }
46         return 0;
47 }
48
49 int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
50 {
51         if (sig-32U < 3) {
52                 errno = EINVAL;
53                 return -1;
54         }
55         return __libc_sigaction(sig, sa, old);
56 }
57
58 weak_alias(__sigaction, sigaction);