1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24
25 /* system headers */
26 #include "system.h"
27
28 #include <osl/diagnose.h>
29 #include <osl/mutex.h>
30 #include <osl/signal.h>
31
32 typedef struct _oslSignalHandlerImpl
33 {
34 oslSignalHandlerFunction Handler;
35 void* pData;
36 struct _oslSignalHandlerImpl* pNext;
37 } oslSignalHandlerImpl;
38
39 static sal_Bool bErrorReportingEnabled = sal_True;
40 static sal_Bool bInitSignal = sal_False;
41 static oslMutex SignalListMutex;
42 static oslSignalHandlerImpl* SignalList;
43
44 /*static*//* ULONG _Export APIENTRY SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec,
45 PEXCEPTIONREGISTRATIONRECORD,
46 PCONTEXTRECORD, PVOID);
47 */
48 /*static*/ ULONG __declspec(dllexport) APIENTRY SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec,
49 PEXCEPTIONREGISTRATIONRECORD,
50 PCONTEXTRECORD, PVOID);
51 static EXCEPTIONREGISTRATIONRECORD ExcptHandler = { 0, SignalHandlerFunction };
52
InitSignal(void)53 static sal_Bool InitSignal( void )
54 {
55 SignalListMutex = osl_createMutex();
56
57 ExcptHandler.ExceptionHandler = (_ERR *) &SignalHandlerFunction;
58 /* DosSetExceptionHandler(&ExcptHandler); */
59
60 return sal_True;
61 }
62
DeInitSignal(void)63 static sal_Bool DeInitSignal( void )
64 {
65 /* DosUnsetExceptionHandler(&ExcptHandler); */
66
67 osl_destroyMutex(SignalListMutex);
68
69 return sal_False;
70 }
71
CallSignalHandler(oslSignalInfo * pInfo)72 static oslSignalAction CallSignalHandler(oslSignalInfo *pInfo)
73 {
74 oslSignalHandlerImpl* pHandler = SignalList;
75 oslSignalAction Action = osl_Signal_ActCallNextHdl;
76
77 while (pHandler != NULL)
78 {
79 if ((Action = pHandler->Handler(pHandler->pData, pInfo)) != osl_Signal_ActCallNextHdl)
80 break;
81
82 pHandler = pHandler->pNext;
83 }
84
85 return Action;
86 }
87
88 /*****************************************************************************/
89 /* SignalHandlerFunction */
90 /*****************************************************************************/
SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec,PEXCEPTIONREGISTRATIONRECORD pERegRec,PCONTEXTRECORD pConRec,PVOID pReserved)91 /*static*/ ULONG __declspec(dllexport) APIENTRY SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec,
92 PEXCEPTIONREGISTRATIONRECORD pERegRec,
93 PCONTEXTRECORD pConRec, PVOID pReserved)
94 {
95 oslSignalInfo Info;
96
97 Info.UserSignal = pERepRec->ExceptionNum;
98 Info.UserData = NULL;
99
100 switch (pERepRec->ExceptionNum)
101 {
102 case XCPT_ACCESS_VIOLATION:
103 Info.Signal = osl_Signal_AccessViolation;
104 break;
105
106 case XCPT_INTEGER_DIVIDE_BY_ZERO:
107 Info.Signal = osl_Signal_IntegerDivideByZero;
108 break;
109
110 case XCPT_BREAKPOINT:
111 Info.Signal = osl_Signal_DebugBreak;
112 break;
113
114 default:
115 Info.Signal = osl_Signal_System;
116 break;
117 }
118
119 switch (CallSignalHandler(&Info))
120 {
121 case osl_Signal_ActCallNextHdl:
122 return (XCPT_CONTINUE_SEARCH);
123
124 case osl_Signal_ActAbortApp:
125 return (XCPT_CONTINUE_SEARCH);
126
127 case osl_Signal_ActKillApp:
128 exit(255);
129 break;
130 }
131
132 return (XCPT_CONTINUE_SEARCH);
133 }
134
135 /*****************************************************************************/
136 /* osl_addSignalHandler */
137 /*****************************************************************************/
osl_addSignalHandler(oslSignalHandlerFunction Handler,void * pData)138 oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction Handler, void* pData)
139 {
140 oslSignalHandlerImpl* pHandler;
141
142 OSL_ASSERT(Handler != NULL);
143
144 if (! bInitSignal)
145 bInitSignal = InitSignal();
146
147 pHandler = (oslSignalHandlerImpl*) calloc(1, sizeof(oslSignalHandlerImpl));
148
149 if (pHandler != NULL)
150 {
151 pHandler->Handler = Handler;
152 pHandler->pData = pData;
153
154 osl_acquireMutex(SignalListMutex);
155
156 pHandler->pNext = SignalList;
157 SignalList = pHandler;
158
159 osl_releaseMutex(SignalListMutex);
160
161 return (pHandler);
162 }
163
164 return (NULL);
165 }
166
167 /*****************************************************************************/
168 /* osl_removeSignalHandler */
169 /*****************************************************************************/
osl_removeSignalHandler(oslSignalHandler Handler)170 sal_Bool SAL_CALL osl_removeSignalHandler(oslSignalHandler Handler)
171 {
172 oslSignalHandlerImpl *pHandler, *pPrevious = NULL;
173
174 OSL_ASSERT(Handler != NULL);
175
176 if (! bInitSignal)
177 bInitSignal = InitSignal();
178
179 osl_acquireMutex(SignalListMutex);
180
181 pHandler = SignalList;
182
183 while (pHandler != NULL)
184 {
185 if (pHandler == Handler)
186 {
187 if (pPrevious)
188 pPrevious->pNext = pHandler->pNext;
189 else
190 SignalList = pHandler->pNext;
191
192 osl_releaseMutex(SignalListMutex);
193
194 if (SignalList == NULL )
195 bInitSignal = DeInitSignal();
196
197 free(pHandler);
198
199 return (sal_True);
200 }
201
202 pPrevious = pHandler;
203 pHandler = pHandler->pNext;
204 }
205
206 osl_releaseMutex(SignalListMutex);
207
208 return (sal_False);
209 }
210
211 /*****************************************************************************/
212 /* osl_raiseSignal */
213 /*****************************************************************************/
osl_raiseSignal(sal_Int32 UserSignal,void * UserData)214 oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 UserSignal, void* UserData)
215 {
216 oslSignalInfo Info;
217 oslSignalAction Action;
218
219 if (! bInitSignal)
220 bInitSignal = InitSignal();
221
222 osl_acquireMutex(SignalListMutex);
223
224 Info.Signal = osl_Signal_User;
225 Info.UserSignal = UserSignal;
226 Info.UserData = UserData;
227
228 Action = CallSignalHandler(&Info);
229
230 osl_releaseMutex(SignalListMutex);
231
232 return (Action);
233 }
234
235 /*****************************************************************************/
236 /* osl_setErrorReporting */
237 /*****************************************************************************/
osl_setErrorReporting(sal_Bool bEnable)238 sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable )
239 {
240 sal_Bool bOld = bErrorReportingEnabled;
241 bErrorReportingEnabled = bEnable;
242
243 return bOld;
244 }
245
246