source: trunk/libs/newlib/src/newlib/libc/signal/signal.c @ 577

Last change on this file since 577 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 5.0 KB
Line 
1/*
2FUNCTION
3<<signal>>---specify handler subroutine for a signal
4
5INDEX
6        signal
7INDEX
8        _signal_r
9
10SYNOPSIS
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
16DESCRIPTION
17<<signal>> provides a simple signal-handling implementation for embedded
18targets.
19
20<<signal>> allows you to request changed treatment for a particular
21signal <[sig]>.  You can use one of the predefined macros <<SIG_DFL>>
22(select system default handling) or <<SIG_IGN>> (ignore this signal)
23as the value of <[func]>; otherwise, <[func]> is a function pointer
24that identifies a subroutine in your program as the handler for this signal.
25
26Some of the execution environment for signal handlers is
27unpredictable; notably, the only library function required to work
28correctly from within a signal handler is <<signal>> itself, and
29only when used to redefine the handler for the current signal value.
30
31Static storage is likewise unreliable for signal handlers, with one
32exception: if you declare a static storage location as `<<volatile
33sig_atomic_t>>', then you may use that location in a signal handler to
34store signal values.
35
36If your signal handler terminates using <<return>> (or implicit
37return), your program's execution continues at the point
38where it was when the signal was raised (whether by your program
39itself, or by an external event).  Signal handlers can also
40use functions such as <<exit>> and <<abort>> to avoid returning.
41
42The alternate function <<_signal_r>> is the reentrant version.
43The extra argument <[reent]> is a pointer to a reentrancy structure.
44
45@c FIXME: do we have setjmp.h and assoc fns?
46
47RETURNS
48If 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
51Otherwise, the result is the previous handler (a function pointer or
52one of the predefined macros).
53
54PORTABILITY
55ANSI C requires <<signal>>.
56
57No supporting OS subroutines are required to link with <<signal>>, but
58it will not have any useful effects, except for software generated signals,
59without 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
80int _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
91int
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
131int 
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
165int
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
196int 
197raise (int sig)
198{
199  return _raise_r (_REENT, sig);
200}
201
202_sig_func_ptr
203signal (int sig,
204        _sig_func_ptr func)
205{
206  return _signal_r (_REENT, sig, func);
207}
208
209int 
210_init_signal (void)
211{
212  return _init_signal_r (_REENT);
213}
214
215int
216__sigtramp (int sig)
217{
218  return __sigtramp_r (_REENT, sig);
219}
220
221#endif
222
223#endif /* !SIGNAL_PROVIDED */
Note: See TracBrowser for help on using the repository browser.