]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/language/c/libc/signals/v2_0/include/signal.inl
Initial revision
[karo-tx-redboot.git] / packages / language / c / libc / signals / v2_0 / include / signal.inl
1 #ifndef CYGONCE_LIBC_SIGNALS_SIGNAL_INL
2 #define CYGONCE_LIBC_SIGNALS_SIGNAL_INL
3 //========================================================================
4 //
5 //      signal.inl
6 //
7 //      Inline functions for implementation of ISO C and POSIX signals
8 //
9 //========================================================================
10 //####ECOSGPLCOPYRIGHTBEGIN####
11 // -------------------------------------------
12 // This file is part of eCos, the Embedded Configurable Operating System.
13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
14 //
15 // eCos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
18 //
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22 // for more details.
23 //
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 //
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
34 //
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
37 //
38 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39 // at http://sources.redhat.com/ecos/ecos-license/
40 // -------------------------------------------
41 //####ECOSGPLCOPYRIGHTEND####
42 //========================================================================
43 //#####DESCRIPTIONBEGIN####
44 //
45 // Author(s):     jlarmour
46 // Contributors:  
47 // Date:          2000-04-18
48 // Purpose:       Implements required inline functions of ISO C and
49 //                POSIX 1003.1 signals
50 // Description:   
51 // Usage:         Do not include this file directly, instead use <signal.h>
52 //
53 //####DESCRIPTIONEND####
54 //
55 //========================================================================
56
57 // CONFIGURATION
58
59 #include <pkgconf/libc_signals.h>  // libc signals configuration
60
61 // INCLUDES
62
63 #include <signal.h>                // Header for this file, just in case
64 #include <cyg/infra/cyg_ass.h>     // Assertion infrastructure
65 #include <cyg/infra/cyg_trac.h>    // Tracing infrastructure
66
67 // GLOBALS
68
69 extern __sighandler_t cyg_libc_signal_handlers[];
70 #ifdef CYGDBG_USE_TRACING
71 extern cyg_uint8 cyg_libc_signals_raise_trace_level;
72 #endif
73
74 // DEFINES
75
76 // The following are overriden by the libc implementation to get a non-inline
77 // version to prevent duplication of code
78 #ifndef CYGPRI_LIBC_SIGNALS_RAISE_INLINE
79 # define CYGPRI_LIBC_SIGNALS_RAISE_INLINE extern __inline__
80 #endif
81
82 #ifndef CYGPRI_LIBC_SIGNALS_SIGNAL_INLINE
83 # define CYGPRI_LIBC_SIGNALS_SIGNAL_INLINE extern __inline__
84 #endif
85
86 // FUNCTION PROTOTYPES
87
88 #ifdef __cplusplus
89 extern "C" {
90 #endif
91
92 // Default signal handler - SIG_DFL
93 extern void cyg_libc_signals_default_handler(int __sig);
94
95 #ifdef CYGSEM_LIBC_SIGNALS_THREAD_SAFE
96 extern cyg_bool cyg_libc_signals_lock_do_lock(void);
97 extern void cyg_libc_signals_lock_do_unlock(void);
98 #endif
99
100 // INLINE FUNCTIONS
101
102 /////////////////////////////
103 // cyg_libc_signals_lock() //
104 /////////////////////////////
105
106 static inline cyg_bool
107 cyg_libc_signals_lock(void)
108 {
109 #ifdef CYGSEM_LIBC_SIGNALS_THREAD_SAFE
110     return cyg_libc_signals_lock_do_lock();
111 #else
112     return true;
113 #endif
114 } // cyg_libc_signals_lock()
115
116 ///////////////////////////////
117 // cyg_libc_signals_unlock() //
118 ///////////////////////////////
119
120 static inline void
121 cyg_libc_signals_unlock(void)
122 {
123 #ifdef CYGSEM_LIBC_SIGNALS_THREAD_SAFE
124     cyg_libc_signals_lock_do_unlock();
125 #else
126     return;
127 #endif
128 } // cyg_libc_signals_unlock()
129
130 // ISO C functions
131
132 //////////////////////////////
133 // signal() - ISO C 7.7.1   //
134 //////////////////////////////
135
136
137 #ifdef CYGIMP_LIBC_SIGNALS_SIGNAL_INLINE
138
139 #ifdef CYGSEM_LIBC_SIGNALS_SIGNAL_SETS_ERRNO
140 # include <errno.h>                 // errno
141 #endif
142
143 CYGPRI_LIBC_SIGNALS_SIGNAL_INLINE __sighandler_t
144 signal(int __sig, __sighandler_t __handler)
145 {
146     __sighandler_t __old_handler;
147     CYG_REPORT_FUNCNAMETYPE( "__signal", "returning %08x" );
148     
149     CYG_REPORT_FUNCARG2( "signal number = %d, requested handler is at %08x",
150                          __sig, __handler );
151
152     // check valid signal - raise should not raise the null signal either
153     if ( (__sig >= CYGNUM_LIBC_SIGNALS) || (__sig <= 0) ) {
154
155 #ifdef CYGSEM_LIBC_SIGNALS_BAD_SIGNAL_FATAL
156         CYG_FAIL("__signal() passed bad signal number");
157 #else
158 # ifdef CYGSEM_LIBC_SIGNALS_SIGNAL_SETS_ERRNO
159         errno = EINVAL;
160 # endif
161         return SIG_ERR;
162 #endif
163     }
164
165     // paranoia
166     CYG_CHECK_DATA_PTR( cyg_libc_signal_handlers,
167                         "signal handler array is invalid!" );
168     if ( (__handler != SIG_IGN) && (__handler != SIG_DFL) )
169         CYG_CHECK_FUNC_PTR( __handler, "__signal() passed invalid handler");
170     
171     if (!cyg_libc_signals_lock()) {
172 #ifdef CYGSEM_LIBC_SIGNALS_SIGNAL_SETS_ERRNO
173         errno = EINTR;
174 #endif
175         return SIG_ERR;
176     } // if
177
178     __old_handler = cyg_libc_signal_handlers[__sig];
179     cyg_libc_signal_handlers[__sig] = __handler;
180     
181     cyg_libc_signals_unlock();
182
183     CYG_REPORT_RETVAL( __old_handler );
184    
185     return __old_handler;
186 } // signal()
187 #endif // ifdef CYGIMP_LIBC_SIGNALS_SIGNAL_INLINE
188
189
190 ///////////////////////////
191 // raise() - ISO C 7.7.2 //
192 ///////////////////////////
193
194 #ifdef CYGIMP_LIBC_SIGNALS_RAISE_INLINE
195
196 #ifdef CYGSEM_LIBC_SIGNALS_RAISE_SETS_ERRNO
197 # include <errno.h>                 // errno
198 #endif
199
200 CYGPRI_LIBC_SIGNALS_RAISE_INLINE int
201 raise(int __sig)
202 {
203     int __ret=0;
204     __sighandler_t __sigfun;
205     
206     CYG_REPORT_FUNCNAMETYPE( "__raise", "returning %d" );
207     
208     CYG_REPORT_FUNCARG1( "signal number = %d", __sig );
209
210     // check valid signal - raise should not raise the null signal either
211     if ( (__sig >= CYGNUM_LIBC_SIGNALS) || (__sig <= 0) ) {
212
213 #ifdef CYGSEM_LIBC_SIGNALS_BAD_SIGNAL_FATAL
214         CYG_FAIL("__raise() passed bad signal number");
215 #else
216 # ifdef CYGSEM_LIBC_SIGNALS_RAISE_SETS_ERRNO
217         errno = EINVAL;
218 # endif
219         return -1;
220 #endif
221     }
222
223     // paranoia
224     CYG_CHECK_DATA_PTR( cyg_libc_signal_handlers,
225                         "signal handler array is invalid!" );
226     
227     if (!cyg_libc_signals_lock()) {
228 #ifdef CYGSEM_LIBC_SIGNALS_RAISE_SETS_ERRNO
229         errno = EINTR;
230 #endif
231         return -1;
232     } // if
233
234     __sigfun = cyg_libc_signal_handlers[__sig];
235
236     if ( __sigfun == SIG_DFL ) {
237         CYG_TRACE0(cyg_libc_signals_raise_trace_level,
238                    "signal handler returned is SIG_DFL");
239         cyg_libc_signals_unlock();
240         cyg_libc_signals_default_handler(__sig);
241     } else if ( __sigfun == SIG_IGN ) {
242         CYG_TRACE0(cyg_libc_signals_raise_trace_level,
243                    "signal handler returned is SIG_IGN");
244         cyg_libc_signals_unlock();
245     } else {
246         CYG_TRACE1(cyg_libc_signals_raise_trace_level,
247                    "signal handler returned is at %08x", __sigfun);
248         // call the signal handler directly
249         cyg_libc_signal_handlers[__sig] = SIG_DFL;
250
251         cyg_libc_signals_unlock();
252         CYG_CHECK_FUNC_PTR( __sigfun, "returned signal handler invalid!");
253
254         (*__sigfun)(__sig);
255     }
256
257     CYG_REPORT_RETVAL( __ret );
258
259     return __ret;
260 } // raise()
261 #endif // ifdef CYGIMP_LIBC_SIGNALS_RAISE_INLINE
262
263
264 #ifdef __cplusplus
265 } // extern "C"
266 #endif 
267
268 #endif // CYGONCE_LIBC_SIGNALS_SIGNAL_INL multiple inclusion protection
269
270 // EOF signal.inl