]>
Commit | Line | Data |
---|---|---|
c4029823 | 1 | /* Copyright (C) 1993, 1996 Free Software Foundation, Inc. |
28f540f4 RM |
2 | This file is part of the GNU C Library. |
3 | ||
4 | The GNU C Library is free software; you can redistribute it and/or | |
5 | modify it under the terms of the GNU Library General Public License as | |
6 | published by the Free Software Foundation; either version 2 of the | |
7 | License, or (at your option) any later version. | |
8 | ||
9 | The GNU C Library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | Library General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Library General Public | |
15 | License along with the GNU C Library; see the file COPYING.LIB. If | |
16 | not, write to the Free Software Foundation, Inc., 675 Mass Ave, | |
17 | Cambridge, MA 02139, USA. */ | |
18 | ||
28f540f4 RM |
19 | #ifndef __GNUC__ |
20 | #error This file uses GNU C extensions; you must compile with GCC. | |
21 | #endif | |
22 | ||
23 | /* Get the definition of `struct sigcontext'. */ | |
24 | #define KERNEL | |
25 | #define sigvec sun_sigvec | |
26 | #define sigstack sun_sigstack | |
27 | #define sigcontext sun_sigcontext | |
28 | #include "/usr/include/sys/signal.h" | |
29 | #undef sigvec | |
30 | #undef sigstack | |
31 | #undef sigcontext | |
32 | #undef NSIG | |
33 | #undef SIGABRT | |
34 | #undef SIGCLD | |
35 | #undef SV_ONSTACK | |
36 | #undef SV_RESETHAND | |
37 | #undef SV_INTERRUPT | |
38 | #undef SA_ONSTACK | |
39 | #undef SA_NOCLDSTOP | |
40 | #undef SIG_ERR | |
41 | #undef SIG_DFL | |
42 | #undef SIG_IGN | |
43 | #undef sigmask | |
44 | #undef SIG_BLOCK | |
45 | #undef SIG_UNBLOCK | |
46 | #undef SIG_SETMASK | |
47 | ||
48 | #include <signal.h> | |
49 | #include <stddef.h> | |
50 | #include <errno.h> | |
51 | ||
52 | /* Defined in __sigvec.S. */ | |
c4029823 UD |
53 | extern int __raw_sigvec (int sig, const struct sigvec *vec, |
54 | struct sigvec *ovec); | |
28f540f4 RM |
55 | |
56 | /* User-specified signal handlers. */ | |
57 | #define mytramp 1 | |
58 | #ifdef mytramp | |
59 | static __sighandler_t handlers[NSIG]; | |
60 | #else | |
61 | #define handlers _sigfunc | |
62 | extern __sighandler_t _sigfunc[]; | |
63 | #endif | |
64 | ||
65 | #if mytramp | |
66 | ||
67 | /* Handler for all signals that are handled by a user-specified function. | |
68 | Saves and restores the general regs %g2-%g7, the %y register, and | |
69 | all the FPU regs (including %fsr), around calling the user's handler. */ | |
70 | static void | |
c4029823 UD |
71 | trampoline (sig, code, context, addr) |
72 | int sig; | |
73 | int code; | |
74 | struct sigcontext *context; | |
75 | void *addr; | |
28f540f4 RM |
76 | { |
77 | int save[4]; | |
78 | ||
79 | /* Save the call-clobbered registers. */ | |
80 | asm volatile ("movem%.l d0-d1/a0-a1, %0" : : "m" (save[0])); | |
81 | ||
82 | /* XXX should save/restore FP regs */ | |
83 | ||
84 | /* Call the user's handler. */ | |
c4029823 | 85 | (*((void (*) __P ((int sig, int code, struct sigcontext *context, |
28f540f4 RM |
86 | PTR addr))) handlers[sig])) |
87 | (sig, code, context, addr); | |
88 | ||
89 | /* Restore the call-clobbered registers. */ | |
90 | asm volatile ("movem%.l %0, d0-d1/a0-a1" : : "g" (save[0]) : | |
91 | "d0", "d1", "a0", "a1"); | |
92 | ||
93 | __sigreturn (context); | |
94 | } | |
95 | ||
96 | #endif | |
97 | ||
98 | int | |
c4029823 UD |
99 | __sigvec (sig, vec, ovec) |
100 | int sig; | |
101 | const struct sigvec *vec; | |
102 | struct sigvec *ovec; | |
28f540f4 RM |
103 | { |
104 | #ifndef mytramp | |
105 | extern void _sigtramp (int); | |
106 | #define trampoline _sigtramp | |
107 | #endif | |
108 | struct sigvec myvec; | |
109 | int mask; | |
110 | __sighandler_t ohandler; | |
111 | ||
112 | if (sig <= 0 || sig >= NSIG) | |
113 | { | |
c4029823 | 114 | __set_errno (EINVAL); |
28f540f4 RM |
115 | return -1; |
116 | } | |
117 | ||
118 | mask = __sigblock(sigmask(sig)); | |
119 | ||
120 | ohandler = handlers[sig]; | |
121 | ||
122 | if (vec != NULL && | |
123 | vec->sv_handler != SIG_IGN && vec->sv_handler != SIG_DFL) | |
124 | { | |
125 | handlers[sig] = vec->sv_handler; | |
126 | myvec = *vec; | |
127 | myvec.sv_handler = trampoline; | |
128 | vec = &myvec; | |
129 | } | |
130 | ||
131 | if (__raw_sigvec(sig, vec, ovec) < 0) | |
132 | { | |
133 | int save = errno; | |
134 | (void) __sigsetmask(mask); | |
135 | errno = save; | |
136 | return -1; | |
137 | } | |
138 | ||
139 | if (ovec != NULL && ovec->sv_handler == trampoline) | |
140 | ovec->sv_handler = ohandler; | |
141 | ||
142 | (void) __sigsetmask(mask); | |
143 | ||
144 | return 0; | |
145 | } |