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 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 63 static sal_Bool DeInitSignal( void ) 64 { 65 /* DosUnsetExceptionHandler(&ExcptHandler); */ 66 67 osl_destroyMutex(SignalListMutex); 68 69 return sal_False; 70 } 71 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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