1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 29 /* system headers */ 30 #include "system.h" 31 32 #include <osl/diagnose.h> 33 #include <osl/mutex.h> 34 #include <osl/signal.h> 35 36 typedef struct _oslSignalHandlerImpl 37 { 38 oslSignalHandlerFunction Handler; 39 void* pData; 40 struct _oslSignalHandlerImpl* pNext; 41 } oslSignalHandlerImpl; 42 43 static sal_Bool bErrorReportingEnabled = sal_True; 44 static sal_Bool bInitSignal = sal_False; 45 static oslMutex SignalListMutex; 46 static oslSignalHandlerImpl* SignalList; 47 48 /*static*//* ULONG _Export APIENTRY SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec, 49 PEXCEPTIONREGISTRATIONRECORD, 50 PCONTEXTRECORD, PVOID); 51 */ 52 /*static*/ ULONG __declspec(dllexport) APIENTRY SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec, 53 PEXCEPTIONREGISTRATIONRECORD, 54 PCONTEXTRECORD, PVOID); 55 static EXCEPTIONREGISTRATIONRECORD ExcptHandler = { 0, SignalHandlerFunction }; 56 57 static sal_Bool InitSignal( void ) 58 { 59 SignalListMutex = osl_createMutex(); 60 61 ExcptHandler.ExceptionHandler = (_ERR *) &SignalHandlerFunction; 62 /* DosSetExceptionHandler(&ExcptHandler); */ 63 64 return sal_True; 65 } 66 67 static sal_Bool DeInitSignal( void ) 68 { 69 /* DosUnsetExceptionHandler(&ExcptHandler); */ 70 71 osl_destroyMutex(SignalListMutex); 72 73 return sal_False; 74 } 75 76 static oslSignalAction CallSignalHandler(oslSignalInfo *pInfo) 77 { 78 oslSignalHandlerImpl* pHandler = SignalList; 79 oslSignalAction Action = osl_Signal_ActCallNextHdl; 80 81 while (pHandler != NULL) 82 { 83 if ((Action = pHandler->Handler(pHandler->pData, pInfo)) != osl_Signal_ActCallNextHdl) 84 break; 85 86 pHandler = pHandler->pNext; 87 } 88 89 return Action; 90 } 91 92 /*****************************************************************************/ 93 /* SignalHandlerFunction */ 94 /*****************************************************************************/ 95 /*static*/ ULONG __declspec(dllexport) APIENTRY SignalHandlerFunction(PEXCEPTIONREPORTRECORD pERepRec, 96 PEXCEPTIONREGISTRATIONRECORD pERegRec, 97 PCONTEXTRECORD pConRec, PVOID pReserved) 98 { 99 oslSignalInfo Info; 100 101 Info.UserSignal = pERepRec->ExceptionNum; 102 Info.UserData = NULL; 103 104 switch (pERepRec->ExceptionNum) 105 { 106 case XCPT_ACCESS_VIOLATION: 107 Info.Signal = osl_Signal_AccessViolation; 108 break; 109 110 case XCPT_INTEGER_DIVIDE_BY_ZERO: 111 Info.Signal = osl_Signal_IntegerDivideByZero; 112 break; 113 114 case XCPT_BREAKPOINT: 115 Info.Signal = osl_Signal_DebugBreak; 116 break; 117 118 default: 119 Info.Signal = osl_Signal_System; 120 break; 121 } 122 123 switch (CallSignalHandler(&Info)) 124 { 125 case osl_Signal_ActCallNextHdl: 126 return (XCPT_CONTINUE_SEARCH); 127 128 case osl_Signal_ActAbortApp: 129 return (XCPT_CONTINUE_SEARCH); 130 131 case osl_Signal_ActKillApp: 132 exit(255); 133 break; 134 } 135 136 return (XCPT_CONTINUE_SEARCH); 137 } 138 139 /*****************************************************************************/ 140 /* osl_addSignalHandler */ 141 /*****************************************************************************/ 142 oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction Handler, void* pData) 143 { 144 oslSignalHandlerImpl* pHandler; 145 146 OSL_ASSERT(Handler != NULL); 147 148 if (! bInitSignal) 149 bInitSignal = InitSignal(); 150 151 pHandler = (oslSignalHandlerImpl*) calloc(1, sizeof(oslSignalHandlerImpl)); 152 153 if (pHandler != NULL) 154 { 155 pHandler->Handler = Handler; 156 pHandler->pData = pData; 157 158 osl_acquireMutex(SignalListMutex); 159 160 pHandler->pNext = SignalList; 161 SignalList = pHandler; 162 163 osl_releaseMutex(SignalListMutex); 164 165 return (pHandler); 166 } 167 168 return (NULL); 169 } 170 171 /*****************************************************************************/ 172 /* osl_removeSignalHandler */ 173 /*****************************************************************************/ 174 sal_Bool SAL_CALL osl_removeSignalHandler(oslSignalHandler Handler) 175 { 176 oslSignalHandlerImpl *pHandler, *pPrevious = NULL; 177 178 OSL_ASSERT(Handler != NULL); 179 180 if (! bInitSignal) 181 bInitSignal = InitSignal(); 182 183 osl_acquireMutex(SignalListMutex); 184 185 pHandler = SignalList; 186 187 while (pHandler != NULL) 188 { 189 if (pHandler == Handler) 190 { 191 if (pPrevious) 192 pPrevious->pNext = pHandler->pNext; 193 else 194 SignalList = pHandler->pNext; 195 196 osl_releaseMutex(SignalListMutex); 197 198 if (SignalList == NULL ) 199 bInitSignal = DeInitSignal(); 200 201 free(pHandler); 202 203 return (sal_True); 204 } 205 206 pPrevious = pHandler; 207 pHandler = pHandler->pNext; 208 } 209 210 osl_releaseMutex(SignalListMutex); 211 212 return (sal_False); 213 } 214 215 /*****************************************************************************/ 216 /* osl_raiseSignal */ 217 /*****************************************************************************/ 218 oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 UserSignal, void* UserData) 219 { 220 oslSignalInfo Info; 221 oslSignalAction Action; 222 223 if (! bInitSignal) 224 bInitSignal = InitSignal(); 225 226 osl_acquireMutex(SignalListMutex); 227 228 Info.Signal = osl_Signal_User; 229 Info.UserSignal = UserSignal; 230 Info.UserData = UserData; 231 232 Action = CallSignalHandler(&Info); 233 234 osl_releaseMutex(SignalListMutex); 235 236 return (Action); 237 } 238 239 /*****************************************************************************/ 240 /* osl_setErrorReporting */ 241 /*****************************************************************************/ 242 sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable ) 243 { 244 sal_Bool bOld = bErrorReportingEnabled; 245 bErrorReportingEnabled = bEnable; 246 247 return bOld; 248 } 249 250