Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / signal / signal.c
blob77d78f04a3b75a4756332a00eb1c569ce1d24b2c
1 /*
2 FUNCTION
3 <<signal>>---specify handler subroutine for a signal
5 INDEX
6 signal
7 INDEX
8 _signal_r
10 SYNOPSIS
11 #include <signal.h>
12 void (*signal(int <[sig]>, void(*<[func]>)(int))) (int);
14 void (*_signal_r(void *<[reent]>, int <[sig]>, void(*<[func]>)(int))) (int);
16 DESCRIPTION
17 <<signal>> provides a simple signal-handling implementation for embedded
18 targets.
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.
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.
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.
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.
42 The alternate function <<_signal_r>> is the reentrant version.
43 The extra argument <[reent]> is a pointer to a reentrancy structure.
45 @c FIXME: do we have setjmp.h and assoc fns?
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>>.
51 Otherwise, the result is the previous handler (a function pointer or
52 one of the predefined macros).
54 PORTABILITY
55 ANSI C requires <<signal>>.
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.
63 * signal.c
64 * Original Author: G. Haley
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.
75 /* _init_signal initialises the signal handlers for each signal. This function
76 is called by crt0 at program startup. */
78 #ifdef SIGNAL_PROVIDED
80 int _dummy_simulated_signal;
82 #else
84 #include <errno.h>
85 #include <signal.h>
86 #include <stddef.h>
87 #include <stdlib.h>
88 #include <reent.h>
89 #include <_syslist.h>
91 #ifdef _REENT_THREAD_LOCAL
92 _Thread_local void (**_tls_sig_func)(int);
93 #endif
95 int
96 _init_signal_r (struct _reent *ptr)
98 int i;
100 if (_REENT_SIG_FUNC(ptr) == NULL)
102 _REENT_SIG_FUNC(ptr) = (_sig_func_ptr *)_malloc_r (ptr, sizeof (_sig_func_ptr) * NSIG);
103 if (_REENT_SIG_FUNC(ptr) == NULL)
104 return -1;
106 for (i = 0; i < NSIG; i++)
107 _REENT_SIG_FUNC(ptr)[i] = SIG_DFL;
110 return 0;
113 _sig_func_ptr
114 _signal_r (struct _reent *ptr,
115 int sig,
116 _sig_func_ptr func)
118 _sig_func_ptr old_func;
120 if (sig < 0 || sig >= NSIG)
122 _REENT_ERRNO(ptr) = EINVAL;
123 return SIG_ERR;
126 if (_REENT_SIG_FUNC(ptr) == NULL && _init_signal_r (ptr) != 0)
127 return SIG_ERR;
129 old_func = _REENT_SIG_FUNC(ptr)[sig];
130 _REENT_SIG_FUNC(ptr)[sig] = func;
132 return old_func;
135 int
136 _raise_r (struct _reent *ptr,
137 int sig)
139 _sig_func_ptr func;
141 if (sig < 0 || sig >= NSIG)
143 _REENT_ERRNO(ptr) = EINVAL;
144 return -1;
147 if (_REENT_SIG_FUNC(ptr) == NULL)
148 func = SIG_DFL;
149 else
150 func = _REENT_SIG_FUNC(ptr)[sig];
152 if (func == SIG_DFL)
153 return _kill_r (ptr, _getpid_r (ptr), sig);
154 else if (func == SIG_IGN)
155 return 0;
156 else if (func == SIG_ERR)
158 _REENT_ERRNO(ptr) = EINVAL;
159 return 1;
161 else
163 _REENT_SIG_FUNC(ptr)[sig] = SIG_DFL;
164 func (sig);
165 return 0;
170 __sigtramp_r (struct _reent *ptr,
171 int sig)
173 _sig_func_ptr func;
175 if (sig < 0 || sig >= NSIG)
177 return -1;
180 if (_REENT_SIG_FUNC(ptr) == NULL && _init_signal_r (ptr) != 0)
181 return -1;
183 func = _REENT_SIG_FUNC(ptr)[sig];
184 if (func == SIG_DFL)
185 return 1;
186 else if (func == SIG_ERR)
187 return 2;
188 else if (func == SIG_IGN)
189 return 3;
190 else
192 _REENT_SIG_FUNC(ptr)[sig] = SIG_DFL;
193 func (sig);
194 return 0;
198 #ifndef _REENT_ONLY
200 int
201 raise (int sig)
203 return _raise_r (_REENT, sig);
206 _sig_func_ptr
207 signal (int sig,
208 _sig_func_ptr func)
210 return _signal_r (_REENT, sig, func);
213 int
214 _init_signal (void)
216 return _init_signal_r (_REENT);
220 __sigtramp (int sig)
222 return __sigtramp_r (_REENT, sig);
225 #endif
227 #endif /* !SIGNAL_PROVIDED */