1 | /* |
---|
2 | FUNCTION |
---|
3 | <<signal>>---specify handler subroutine for a signal |
---|
4 | |
---|
5 | INDEX |
---|
6 | signal |
---|
7 | INDEX |
---|
8 | _signal_r |
---|
9 | |
---|
10 | SYNOPSIS |
---|
11 | #include <signal.h> |
---|
12 | void (*signal(int <[sig]>, void(*<[func]>)(int))) (int); |
---|
13 | |
---|
14 | void (*_signal_r(void *<[reent]>, int <[sig]>, void(*<[func]>)(int))) (int); |
---|
15 | |
---|
16 | DESCRIPTION |
---|
17 | <<signal>> provides a simple signal-handling implementation for embedded |
---|
18 | targets. |
---|
19 | |
---|
20 | <<signal>> allows you to request changed treatment for a particular |
---|
21 | signal <[sig]>. You can use one of the predefined macros <<SIG_DFL>> |
---|
22 | (select system default handling) or <<SIG_IGN>> (ignore this signal) |
---|
23 | as the value of <[func]>; otherwise, <[func]> is a function pointer |
---|
24 | that identifies a subroutine in your program as the handler for this signal. |
---|
25 | |
---|
26 | Some of the execution environment for signal handlers is |
---|
27 | unpredictable; notably, the only library function required to work |
---|
28 | correctly from within a signal handler is <<signal>> itself, and |
---|
29 | only when used to redefine the handler for the current signal value. |
---|
30 | |
---|
31 | Static storage is likewise unreliable for signal handlers, with one |
---|
32 | exception: if you declare a static storage location as `<<volatile |
---|
33 | sig_atomic_t>>', then you may use that location in a signal handler to |
---|
34 | store signal values. |
---|
35 | |
---|
36 | If your signal handler terminates using <<return>> (or implicit |
---|
37 | return), your program's execution continues at the point |
---|
38 | where it was when the signal was raised (whether by your program |
---|
39 | itself, or by an external event). Signal handlers can also |
---|
40 | use functions such as <<exit>> and <<abort>> to avoid returning. |
---|
41 | |
---|
42 | The alternate function <<_signal_r>> is the reentrant version. |
---|
43 | The extra argument <[reent]> is a pointer to a reentrancy structure. |
---|
44 | |
---|
45 | @c FIXME: do we have setjmp.h and assoc fns? |
---|
46 | |
---|
47 | RETURNS |
---|
48 | If your request for a signal handler cannot be honored, the result is |
---|
49 | <<SIG_ERR>>; a specific error number is also recorded in <<errno>>. |
---|
50 | |
---|
51 | Otherwise, the result is the previous handler (a function pointer or |
---|
52 | one of the predefined macros). |
---|
53 | |
---|
54 | PORTABILITY |
---|
55 | ANSI C requires <<signal>>. |
---|
56 | |
---|
57 | No supporting OS subroutines are required to link with <<signal>>, but |
---|
58 | it will not have any useful effects, except for software generated signals, |
---|
59 | without an operating system that can actually raise exceptions. |
---|
60 | */ |
---|
61 | |
---|
62 | /* |
---|
63 | * signal.c |
---|
64 | * Original Author: G. Haley |
---|
65 | * |
---|
66 | * signal associates the function pointed to by func with the signal sig. When |
---|
67 | * a signal occurs, the value of func determines the action taken as follows: |
---|
68 | * if func is SIG_DFL, the default handling for that signal will occur; if func |
---|
69 | * is SIG_IGN, the signal will be ignored; otherwise, the default handling for |
---|
70 | * the signal is restored (SIG_DFL), and the function func is called with sig |
---|
71 | * as its argument. Returns the value of func for the previous call to signal |
---|
72 | * for the signal sig, or SIG_ERR if the request fails. |
---|
73 | */ |
---|
74 | |
---|
75 | /* _init_signal initialises the signal handlers for each signal. This function |
---|
76 | is called by crt0 at program startup. */ |
---|
77 | |
---|
78 | #ifdef SIGNAL_PROVIDED |
---|
79 | |
---|
80 | int _dummy_simulated_signal; |
---|
81 | |
---|
82 | #else |
---|
83 | |
---|
84 | #include <errno.h> |
---|
85 | #include <signal.h> |
---|
86 | #include <stddef.h> |
---|
87 | #include <stdlib.h> |
---|
88 | #include <reent.h> |
---|
89 | #include <_syslist.h> |
---|
90 | |
---|
91 | int |
---|
92 | _init_signal_r (struct _reent *ptr) |
---|
93 | { |
---|
94 | int i; |
---|
95 | |
---|
96 | if (ptr->_sig_func == NULL) |
---|
97 | { |
---|
98 | ptr->_sig_func = (_sig_func_ptr *)_malloc_r (ptr, sizeof (_sig_func_ptr) * NSIG); |
---|
99 | if (ptr->_sig_func == NULL) |
---|
100 | return -1; |
---|
101 | |
---|
102 | for (i = 0; i < NSIG; i++) |
---|
103 | ptr->_sig_func[i] = SIG_DFL; |
---|
104 | } |
---|
105 | |
---|
106 | return 0; |
---|
107 | } |
---|
108 | |
---|
109 | _sig_func_ptr |
---|
110 | _signal_r (struct _reent *ptr, |
---|
111 | int sig, |
---|
112 | _sig_func_ptr func) |
---|
113 | { |
---|
114 | _sig_func_ptr old_func; |
---|
115 | |
---|
116 | if (sig < 0 || sig >= NSIG) |
---|
117 | { |
---|
118 | ptr->_errno = EINVAL; |
---|
119 | return SIG_ERR; |
---|
120 | } |
---|
121 | |
---|
122 | if (ptr->_sig_func == NULL && _init_signal_r (ptr) != 0) |
---|
123 | return SIG_ERR; |
---|
124 | |
---|
125 | old_func = ptr->_sig_func[sig]; |
---|
126 | ptr->_sig_func[sig] = func; |
---|
127 | |
---|
128 | return old_func; |
---|
129 | } |
---|
130 | |
---|
131 | int |
---|
132 | _raise_r (struct _reent *ptr, |
---|
133 | int sig) |
---|
134 | { |
---|
135 | _sig_func_ptr func; |
---|
136 | |
---|
137 | if (sig < 0 || sig >= NSIG) |
---|
138 | { |
---|
139 | ptr->_errno = EINVAL; |
---|
140 | return -1; |
---|
141 | } |
---|
142 | |
---|
143 | if (ptr->_sig_func == NULL) |
---|
144 | func = SIG_DFL; |
---|
145 | else |
---|
146 | func = ptr->_sig_func[sig]; |
---|
147 | |
---|
148 | if (func == SIG_DFL) |
---|
149 | return _kill_r (ptr, _getpid_r (ptr), sig); |
---|
150 | else if (func == SIG_IGN) |
---|
151 | return 0; |
---|
152 | else if (func == SIG_ERR) |
---|
153 | { |
---|
154 | ptr->_errno = EINVAL; |
---|
155 | return 1; |
---|
156 | } |
---|
157 | else |
---|
158 | { |
---|
159 | ptr->_sig_func[sig] = SIG_DFL; |
---|
160 | func (sig); |
---|
161 | return 0; |
---|
162 | } |
---|
163 | } |
---|
164 | |
---|
165 | int |
---|
166 | __sigtramp_r (struct _reent *ptr, |
---|
167 | int sig) |
---|
168 | { |
---|
169 | _sig_func_ptr func; |
---|
170 | |
---|
171 | if (sig < 0 || sig >= NSIG) |
---|
172 | { |
---|
173 | return -1; |
---|
174 | } |
---|
175 | |
---|
176 | if (ptr->_sig_func == NULL && _init_signal_r (ptr) != 0) |
---|
177 | return -1; |
---|
178 | |
---|
179 | func = ptr->_sig_func[sig]; |
---|
180 | if (func == SIG_DFL) |
---|
181 | return 1; |
---|
182 | else if (func == SIG_ERR) |
---|
183 | return 2; |
---|
184 | else if (func == SIG_IGN) |
---|
185 | return 3; |
---|
186 | else |
---|
187 | { |
---|
188 | ptr->_sig_func[sig] = SIG_DFL; |
---|
189 | func (sig); |
---|
190 | return 0; |
---|
191 | } |
---|
192 | } |
---|
193 | |
---|
194 | #ifndef _REENT_ONLY |
---|
195 | |
---|
196 | int |
---|
197 | raise (int sig) |
---|
198 | { |
---|
199 | return _raise_r (_REENT, sig); |
---|
200 | } |
---|
201 | |
---|
202 | _sig_func_ptr |
---|
203 | signal (int sig, |
---|
204 | _sig_func_ptr func) |
---|
205 | { |
---|
206 | return _signal_r (_REENT, sig, func); |
---|
207 | } |
---|
208 | |
---|
209 | int |
---|
210 | _init_signal (void) |
---|
211 | { |
---|
212 | return _init_signal_r (_REENT); |
---|
213 | } |
---|
214 | |
---|
215 | int |
---|
216 | __sigtramp (int sig) |
---|
217 | { |
---|
218 | return __sigtramp_r (_REENT, sig); |
---|
219 | } |
---|
220 | |
---|
221 | #endif |
---|
222 | |
---|
223 | #endif /* !SIGNAL_PROVIDED */ |
---|