The code fragment below shows how to set a handler while the calling thread is executing driver code. In the event of an exception, OS/2 calls the handler function, which jumps back to the point of setjmp().
#define INCL_DOS
#include <os2.h>
#include <setjmp.h>
// this exception registration record extends the OS/2-defined one in BSEXCPT.H
// by adding a C jmp_buf at the end
struct _regrec {
PULONG pNext;
PFN pfnHandler;
jmp_buf jmp;
}
typedef struct _regrec REGREC, *PREGREC;
// -------------------------------------------------------------------------
// an exception handler function that jumps back to setjmp()
ULONG _System DriverHandler( PEXCEPTIONREPORTRECORD p1,
PREGREC p2,
PCONTEXTRECORD p3,
PVOID pv )
{
// handle interesting exceptions
switch( p1->ExceptionNum ) {
case XCPT_ACCESS_VIOLATION:
case XCPT_INTEGER_DIVIDE_BY_ZERO:
case XCPT_INTEGER_OVERFLOW:
case XCPT_PROCESS_TERMINATE:
case XCPT_ASYNC_PROCESS_TERMINATE:
// setjmp() will return p1->ExceptionNum
longjmp(p2)->jmp, p1->ExceptionNum );
}
// not interested; system should continue search
return XCPT_CONTINUE_SEARCH;
}
// -------------------------------------------------------------------------
// example of an exported driver function; return TRUE upon success
LONG _System ExportedDriverFunction( PVOID p )
{
REGREC regrec;
ULONG ulException;
LONG lResult;
regrec.pfnHandler = (PFN)DriverHandler;
DosSetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD)®rec );
// get thread state; normally rets 0, rets non-zero after longjmp()
ulException = setjmp( regrec.jmp );
if( ulException ) {
// an exception occurred
// clean up here: release memory, semaphores
// must check for exiting thread case
switch( ulException ) {
case XCPT_PROCESS_TERMINATE:
case XCPT_ASYNC_PROCESS_TERMINATE:
// thread is ending or being terminated
DosUnsetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD)®rec );
DosExit( EXIT_THREAD, 0 );
}
WinSetErrorInfo( ... );
lResult = FALSE;
goto depart;
}
// do the work of the exported function here
lResult = TRUE;
depart:
DosUnsetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD)®rec );
return lResult;
}