How do I set an exception handler?

/*
 * 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


[Back: How do I get the error message from a DOS API call?]
[Next: How can I determine a diskette format and if a disk is in a drive?]