Annotation of prex/usr/lib/posix/signal/__exception.c, Revision 1.1.1.1
1.1 nbrk 1: /*
2: * Copyright (c) 2005, Kohsuke Ohtani
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. Neither the name of the author nor the names of any co-contributors
14: * may be used to endorse or promote products derived from this software
15: * without specific prior written permission.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
28: */
29:
30: #include <prex/prex.h>
31: #include <prex/signal.h>
32:
33: #include <unistd.h>
34: #include <signal.h>
35: #include <stdlib.h>
36:
37: void __exception_init(void);
38: void __exception_exit(void);
39:
40: struct sigaction __sig_act[NSIG];
41: sigset_t __sig_mask;
42: sigset_t __sig_pending;
43:
44: #ifdef _REENTRANT
45: volatile mutex_t __sig_lock;
46: #endif
47:
48: /*
49: * Process all pending and unmasked signal
50: *
51: * return 0 if at least one pending signal was processed.
52: * return -1 if no signal was processed.
53: */
54: int
55: __sig_flush(void)
56: {
57: int sig;
58: sigset_t active, org_mask;
59: struct sigaction action;
60: struct siginfo si;
61: int rc = -1;
62:
63: sig = 1;
64: for (;;) {
65: SIGNAL_LOCK();
66: active = __sig_pending & ~__sig_mask;
67: action = __sig_act[sig];
68: SIGNAL_UNLOCK();
69:
70: if (active == 0)
71: break;
72: if (active & sigmask(sig)) {
73:
74: SIGNAL_LOCK();
75: org_mask = __sig_mask;
76: __sig_mask |= action.sa_mask;
77: SIGNAL_UNLOCK();
78:
79: if (action.sa_handler == SIG_DFL) {
80: /* Default */
81: switch (sig) {
82: case SIGCHLD:
83: /* XXX: */
84: break;
85: default:
86: exit(0);
87: }
88: } else if (action.sa_handler != SIG_IGN) {
89: /* User defined */
90: if (action.sa_flags & SA_SIGINFO) {
91: si.si_signo = sig;
92: si.si_code = 0;
93: si.si_value.sival_int = 0;
94: action.sa_sigaction(sig, &si, NULL);
95: } else {
96: action.sa_handler(sig);
97: }
98: }
99: SIGNAL_LOCK();
100: __sig_pending &= ~sigmask(sig);
101: __sig_mask = org_mask;
102: SIGNAL_UNLOCK();
103:
104: switch (sig) {
105: case SIGILL:
106: case SIGTRAP:
107: case SIGFPE:
108: case SIGSEGV:
109: for (;;); /* exception from kernel */
110: break;
111: }
112: if (action.sa_handler != SIG_IGN)
113: rc = 0; /* Signal is processed */
114: }
115:
116: if (++sig >= NSIG)
117: sig = 1;
118: }
119: return rc;
120: }
121:
122: /*
123: * Exception handler for signal emulation
124: */
125: static void
126: __exception_handler(int excpt)
127: {
128:
129: if (excpt > 0 && excpt <= NSIG) {
130:
131: SIGNAL_LOCK();
132:
133: if (__sig_act[excpt].sa_handler != SIG_IGN)
134: __sig_pending |= sigmask(excpt);
135:
136: SIGNAL_UNLOCK();
137: }
138: __sig_flush();
139: exception_return();
140: }
141:
142: /*
143: * Initialize exception
144: */
145: void
146: __exception_init(void)
147: {
148: int i;
149:
150: #ifdef _REENTRANT
151: mutex_init(&__sig_lock);
152: #endif
153: exception_setup(NULL);
154:
155: __sig_mask = 0;
156: __sig_pending = 0;
157:
158: for (i = 0; i < NSIG; i++) {
159: __sig_act[i].sa_flags = 0;
160: __sig_act[i].sa_handler = SIG_DFL;
161: }
162:
163: /* Install exception handler */
164: exception_setup(__exception_handler);
165: }
166:
167: /*
168: * Clean up
169: */
170: void
171: __exception_exit(void)
172: {
173:
174: #ifdef _REENTRANT
175: mutex_destroy(&__sig_lock);
176: #endif
177: exception_setup(NULL);
178: }
CVSweb