ILE C/C++ Programmer's Guide

Using ILE Condition Handlers

ILE condition handlers allow you to register one or more condition handlers at run time. To register an ILE condition handler, use the Register ILE Condition Handler (CEEHDLR) bindable API. Include the <lecond.h> header file in your source code when using these APIs. ILE condition handlers may be unregistered by calling the Unregister ILE Condition Handler (CEEHDLU) bindable API.

Condition handlers are exception handlers that are registered at run time by using the Register ILE Condition Handler (CEEHDLR) bindable API. They are used to handle, percolate or promote exceptions. The exceptions are presented to the condition handlers in the form of an ILE condition.

When to Use an ILE Condition Handler

If you want to have a consistent mechanism of condition handling across several ILE languages (or for scoping exception handling to a call stack entry), use the ILE bindable API CEEHDLR. Unlike the signal handler ,which is scoped to the activation group, CEEHDLR is scoped to the function that calls it.

The ILE condition handler uses ILE conditions to allow greater cross-system consistency. An ILE condition is a system-independent representation of an error condition in an HLL.

Example of ILE Source that Uses Condition Handlers

The following example shows the source for a program MYPGM:

Figure 174. T1520XH5 -- ILE C Source to Use ILE Condition Handlers -- main()




#include <lecond.h>
#include <stdio.h>
void my_handler(_FEEDBACK *cond, _POINTER *token, _INT4 *rc, _FEEDBACK *new );
void main_handler(_FEEDBACK *cond, _POINTER *token, _INT4 *rc, _FEEDBACK *new );
void fred(void)
{
_HDLR_ENTRY hdlr=my_handler;
char *p = NULL;
CEEHDLR(&hdlr, NULL,NULL);
*p = 'x'; /* exception */
CEEHDLU(&hdlr,NULL);
}
int main(void)
{
_HDLR_ENTRY hdlr=main_handler;
CEEHDLR(&hdlr,NULL,NULL);
fred();
}

In the example MYPGM:

The main() function is a control boundary. The exception is considered unhandled, so a function check is sent to function fred(). Handlers my_handler and main_handler are called again, this time for the function check. Neither of them handle the function check, so the program ends abnormally and a CEE9901 message is sent to the caller of the main() function.

Example of a Service Program that Provides ILE Condition Handlers

The following example shows the source for the service program HANDLERS:

Figure 175. T1520XH6 -- ILE C Source to Use ILE Condition Handlers -- Service Program




#include <signal.h>
#include <stdio.h>
#include <lecond.h>
/* HANDLERS *SRVPGM (*CALLER) */
void my_handler(_FEEDBACK *cond, _POINTER *token, _INT4 *rc, _FEEDBACK *new)
{
return;
}
void main_handler(_FEEDBACK *cond, _POINTER *token, _INT4 *rc, _FEEDBACK *new)
{
printf("In main_handler\n");
}

Examples of Handling an Exception

The following example shows how to use a condition handler to handle an exception. In the example:

The following steps create and run the source in Figure 176.

  1. To create the program T1520IC6, enter:

    CRTBNDC PGM(MYLIB/T1520IC6) SRCFILE(QCPPLE/QACSRC)
  2. To run the program T1520IC6, enter:

    CALL PGM(MYLIB/T1520IC6)

    The output is:

    +--------------------------------------------------------------------------------+
    |  condition was raised: Facility_ID = MCH, MsgNo = 0x1211                       |
    |  The condition was handled.                                                    |
    |  Press ENTER to end terminal session.                                          |
    +--------------------------------------------------------------------------------+

Figure 176. T1520IC6 -- ILE C Source to Use ILE Condition Handlers




/* This program uses the ILE bindable API CEEHDLR to handle a */
/* condition. */
#include <stdio.h>
#include <stdlib.h>
#include <leawi.h>
/* A condition handler registered by a call to CEEHDLR in main(). */
void cond_hdlr( _FEEDBACK *cond, _POINTER *token, _INT4 *rc, _FEEDBACK *new )
{
*rc = CEE_HDLR_RESUME; /* handle the condition */
printf("condition was raised: Facility_ID = %.3s, MsgNo = 0x%4.4x\n",
cond->Facility_ID, cond->MsgNo);
}
int main(void)
{
_HDLR_ENTRY hdlr = cond_hdlr;
_FEEDBACK fc;
int x,y;
int zero = 0;
/* Register the condition handler. */
CEEHDLR(&hdlr, NULL, &fc);
if (fc.MsgNo != CEE0000)
{
printf("Failed to register the condition handler\n");
exit(88);
}
/* Cause a divide by zero condition. */
x = y / zero;
/* The code resumes here after the condition has been handled. */
printf("The condition was handled.\n");
}

Example of Handling a Divide-By-Zero Exception

In this example:

This example uses the source shown in Figure 177.

  1. To create the program T1520IC7, enter:

    CRTBNDC PGM(MYLIB/T1520IC7) SRCFILE(QCPPLE/QACSRC)
  2. To run the program T1520IC7, enter:

    CALL PGM(MYLIB/T1520IC7)

    The output is:

    +--------------------------------------------------------------------------------+
    |in fred_hdlr, percolate exception.                                              |
    |in main hdlr: Facility_ID = MCH, MsgNo = 0x1211                                 |
    |Resume here because resume cursor not moved and main_hdlr handled the exception.|
    |A condition was percolated from fred() to main() and was then handled.          |
    |Press ENTER to end terminal session.                                            |
    +--------------------------------------------------------------------------------+

Figure 177. T1520IC7 -- ILE C Source to Percolate a Message to Handle a Condition




/* This program uses the ILE bindable API CEEHDLR to enable handlers */
/* that percolate and handle a condition. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <leawi.h>
/* A condition handler registered by a call to CEEHDLR in fred(). */
void fred_hdlr( _FEEDBACK *cond, _POINTER *token, _INT4 *rc, _FEEDBACK *new )
{
if (!memcmp(cond->Facility_ID, "MCH", 3) && cond->MsgNo == 0x1211)
{
*rc = CEE_HDLR_PERC; /* ... let it percolate to main ... */
printf("in fred_hdlr, percolate exception.\n");
}
else
{
*rc = CEE_HDLR_RESUME; /* ... otherwise handle it. */
printf("in fred_hdlr, handle exception.\n");
}
}
/* A condition handler registered by a call to CEEHDLR in main(). */
void main_hdlr( _FEEDBACK *cond, _POINTER *token, _INT4 *rc, _FEEDBACK *new )
{
printf("in main hdlr: Facility_ID = %.3s, MsgNo = 0x%4.4x\n",
cond->Facility_ID, cond->MsgNo);
**(_INT4 **)token = 1; /* Update the user's token. */
*rc = CEE_HDLR_RESUME; /* Handle the condition */
}
int fred(void)
{
_HDLR_ENTRY hdlr = fred_hdlr;
_FEEDBACK fc;
int x,y, zero = 0;
/* Register the handler without a token. */
CEEHDLR(&hdlr, NULL, &fc);
if (fc.MsgNo != CEE0000)
{
printf("Failed to register the condition handler\n");
exit(88);
}
/* Cause a divide by zero condition. */
x = y / zero;
printf("Resume here because resume cursor not moved and main_hdlr"
" handled the exception\n");
}

int main(void)
{
_HDLR_ENTRY hdlr = main_hdlr;
_FEEDBACK fc;
volatile _INT4 token=0, *tokenp = &token;
/* Register the handler with a token of type _INT4. */
CEEHDLR(&hdlr, (_POINTER *)&tokenp, &fc);


if (fc.MsgNo != CEE0000)
{
printf("Failed to register the condition handler\n");
exit(99);
}
fred();
/* See if the condition handler for main() updated the token. */
if (*tokenp == 1)
printf("A condition was percolated from fred() to main() and"
" was then handled.\n");
}

Example of Promoting an Exception

In the following example:

The source code in program T1520IC8 is shown in Figure 178.

  1. To create the program T1520IC8, , enter:

    CRTBNDC PGM(MYLIB/T1520IC8) SRCFILE(QCPPLE/QACSRC)
  2. To run the program T1520IC8, enter:

    CALL PGM(MYLIB/T1520IC8)

    The output is status information messages:

    +--------------------------------------------------------------------------------+
    |in fred_hdlr: moving resumes. Facility_ID = MCH, MsgNo = 0x1211                 |
    |promoting condition....                                                         |
    |A condition was promoted from MCH1211 to CEE9902 by fred() and was handled by   |
    | the condition handler enabled in main().                                       |
    |Press ENTER to end terminal session.                                            |
    +--------------------------------------------------------------------------------+

Figure 178. T1520IC8 -- ILE C Source to Promote a Message to Handle a Condition




/* This program uses the ILE bindable API CEEHDLR to promote a */
/* divide by zero condition to a CEE9902. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <leawi.h>


/* A condition handler registered by a call to CEEHDLR in fred(). */
void fred_hdlr( _FEEDBACK *cond, _POINTER *token, _INT4 *rc, _FEEDBACK *new )
{
_INT4 type=1;
CEEMRCR(&type,NULL); /* Move the resume cursor to the resume point */
/* in main(). */
/* If its a divide by zero error ... */
printf("in fred_hdlr: moving resumes. ");
printf("Facility_ID = %.3s, MsgNo = 0x%4.4x\n",
cond->Facility_ID, cond->MsgNo);
if (!memcmp(cond->Facility_ID, "MCH", 3) && cond->MsgNo == 0x1211)
{
*rc = CEE_HDLR_PROM; /*... Promote the condition to unexpected error.*/
*new = *cond;
memcpy(new->Facility_ID, "CEE", 3);
new->MsgNo = 9902;
printf("promoting condition....\n");
}
else
{
*rc = CEE_HDLR_PERC; /*...Otherwise,Percolate to the next handler. */
printf("percolating condition....\n");
}
}
/* A condition handler registered by a call to CEEHDLR in main(). */
void main_hdlr( _FEEDBACK *cond, _POINTER *token, _INT4 *rc, _FEEDBACK *new )
{
if (!memcmp(cond->Facility_ID,"CEE",3) && cond->MsgNo == 9902;)
**(_INT4 **)token = 1; /* Got the promoted CEE9902. */
else
**(_INT4 **)token = 2; /* It is not a CEE9902. */
*rc = CEE_HDLR_RESUME; /* Handle the condition. */
}
int fred(void)
{
_HDLR_ENTRY hdlr = fred_hdlr;
_FEEDBACK fc;
int x,y, zero = 0;
/* Register the handler without a token. */
CEEHDLR(&hdlr, NULL, &fc);
if (fc.MsgNo != CEE0000)
{
printf("Failed to register the condition handler\n");
exit(88);
}

/* Cause a divide by zero condition. */
x = y / zero;
/* This is not the resume point because of the call to CEEMRCR in */
/* fred_hdlr. */
{
printf("This is not the resume point: should not get here\n");
}
}


int main(void)
{
_HDLR_ENTRY hdlr = main_hdlr;
_FEEDBACK fc;
volatile _INT4 token=0, *tokenp = &token;
/* Register the handler with a token of type _INT4. */
CEEHDLR(&hdlr, (_POINTER *)&tokenp, &fc);
if (fc.MsgNo != CEE0000)
{
printf("Failed to register the condition handler\n");
exit(99);
}
fred();
/* See if the condition handler for main() received the promoted */
/* condition. */
if (*tokenp == 1)
printf("A condition was promoted from MCH1211 to CEE9902 by "
"fred() and was handled by the condition handler enabled "
"in main().\n");
}


[ Top of Page | Previous Page | Next Page | Table of Contents ]