/* * Simple example of an exception handler */ #define INCL_DOS #include <os2.h> #include <setjmp.h> #include <stdio.h> #include <string.h> extern int main(void); /* * Exception registration record. Stored on stack, with first * pointer to next registeration record, second pointer to * exception handler, and the rest defined by the author of * the exception handler. */ typedef struct { struct _EXCEPTIONREGISTRATIONRECORD * volatile prev_structure; _ERR * volatile ExceptionHandler; jmp_buf env; } MYEXCEPTIONREGISTRATIONRECORD, *PMYEXCEPTIONREGISTRATIONRECORD; /* * Exception handler that returns traps via longjmp(). */ extern ULONG APIENTRY MyExceptionHandler (PEXCEPTIONREPORTRECORD pReportRecord, PEXCEPTIONREGISTRATIONRECORD pRegRecord, PCONTEXTRECORD pContextRecord, PVOID pReserved) { ULONG rc = XCPT_CONTINUE_SEARCH; if (pReportRecord->ExceptionNum == XCPT_ACCESS_VIOLATION) longjmp(((PMYEXCEPTIONREGISTRATIONRECORD) pRegRecord)->env, -1); /* * If we return to here then we could not handle the exception. */ return rc; } extern BOOL Trapper(PSZ psz) { MYEXCEPTIONREGISTRATIONRECORD myExceptionRegRecord; /* * Insert my exception handler into the chain. */ myExceptionRegRecord.prev_structure = NULL; myExceptionRegRecord.ExceptionHandler = MyExceptionHandler; DosSetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD) &myExceptionRegRecord); if (setjmp(myExceptionRegRecord.env)) goto OnException; /* * Now go about my business in safety. */ if (strlen(psz)) printf("Trapper says okay to '%s'\n", psz); else printf("Trapper says it is empty\n"); /* * I'm done, so unchain my exception handler. */ DosUnsetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)&myExceptionRegRecord) return TRUE; /* * The code below is only executed if a trap occurs. */ OnException: printf("Trapper says 'ouch!'\n"); DosUnsetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)&myExceptionRegRecord) return FALSE; } extern int main() { Trapper("Hello"); Trapper(NULL); Trapper(""); Trapper((PSZ) 42); Trapper("Goodbye"); return 0; }
Credit: Dan Kehn