Example in ILE C: Retrieving exit point and exit program information
This ILE C program retrieves exit point and exit program information. It then resolves to each exit program and calls the exit program.
The Retrieve Exit Information (QusRetrieveExitInformation) API returns a continuation handle when it has more information to return than what can fit in the receiver variable.
Note: By using the code examples,
you agree to the terms of the Code license and disclaimer information.
/********************************************************************/
/* PROGRAM: Retrieve Exit Point and Exit Program Information */
/* */
/* LANGUAGE: ILE C */
/* */
/* DESCRIPTION: This program retrieves exit point and exit */
/* program information. After retrieving the */
/* exit point information, the program resolves to */
/* each associated exit program and calls each exit */
/* program. */
/* */
/* APIs USED: QusRetrieveExitInformation - Retrieve Exit */
/* Information */
/* */
/********************************************************************/
/********************************************************************/
/* Includes */
/********************************************************************/
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <except.h>
#include <qusrgfa2.h>
#include <qusec.h>
#include <qmhchgem.h>
#include <miptrnam.h>
#include <qliept.h>
/********************************************************************/
/* Prototypes */
/********************************************************************/
typedef void Pgm_OS(void *arg,...);
#pragma linkage(Pgm_OS,OS)
/********************************************************************/
/* Structures */
/********************************************************************/
typedef struct { /* Error code */
Qus_EC_t ec_fields;
char exception_data[100];
} error_code_struct;
/********************************************************************/
/* FUNCTION NAME: RSLVSP_PGM_HDLR */
/* */
/* FUNCTION : This function handles all exceptions that */
/* may occur while resolving to the exit */
/* program. */
/* */
/* INPUT: Interrupt handler information */
/* */
/* OUTPUT: NONE */
/* */
/********************************************************************/
void RSLVSP_PGM_HDLR(_INTRPT_Hndlr_Parms_T *errmsg)
{
error_code_struct Error_Code;
/******************************************************************/
/* Set the rsl_ok indicator to not valid. */
/******************************************************************/
int *rsl_ok = (int *)(errmsg>Com_Area);
*rsl_ok = 0;
/******************************************************************/
/* Let message handler know that the program handled the message */
/* and to remove it from the job log. */
/******************************************************************/
Error_Code.ec_fields.Bytes_Provided=0;
QMHCHGEM(&(errmsg>Target),
0,
(char *)&errmsg>Msg_Ref_Key,
"*REMOVE ",
"",
0,
&Error_Code);
}
/********************************************************************/
/* FUNCTION NAME: Call_Exit_Program */
/* */
/* FUNCTION : This function calls the exit programs that */
/* were retrieved from the registration facility */
/* repository. */
/* */
/* INPUT: Information retrieved */
/* */
/* OUTPUT: NONE */
/* */
/********************************************************************/
void Call_Exit_Program(char *rcv_var)
{
int num_exit_pgms,
i;
char exit_pgm_name[10],
exit_pgm_lib[10],
info_for_exit_pgm[10],
*rcv_ptr;
volatile int rsl_ok;
Pgm_OS *exit_pgm_ptr;
/******************************************************************/
/* Save the number of exit programs returned and set the pointer */
/* to point to the first exit program entry. */
/******************************************************************/
rcv_ptr=rcv_var;
num_exit_pgms=((Qus_EXTI0200_t *)rcv_ptr)>Number_Programs_Returned;
rcv_ptr += ((Qus_EXTI0200_t *)rcv_ptr)>Offset_Program_Entry;
rsl_ok=1;
for (i=0; i<num_exit_pgms; i++)
{
memcpy(exit_pgm_name,
((Qus_EXTI0200_Entry_t *)rcv_ptr)>Program_Name,10);
memcpy(exit_pgm_lib,
((Qus_EXTI0200_Entry_t *)rcv_ptr)>Program_Library,10);
/****************************************************************/
/* Resolve to the exit program. If an error occurs on the */
/* resolve operation to the library, the rsl_ok indicator is */
/* set to failed in the RSL_PGM_HDLR exception handler. */
/* The rslvsp MI instruction signals all errors to this */
/* program; therefore, enable the exception handler to capture */
/* any errors that may occur. */
/****************************************************************/
#pragma exception_handler (RSLVSP_PGM_HDLR,rsl_ok,0,_C2_MH_ESCAPE)
exit_pgm_ptr=((Pgm_OS *)rslvsp(_Program,
exit_pgm_name,
exit_pgm_lib,
_AUTH_POINTER));
#pragma disable_handler
/****************************************************************/
/* If the resolve operation is successful, call the exit */
/* program. If not, move on to the next exit program. */
/****************************************************************/
if (rsl_ok)
{
exit_pgm_ptr(info_for_exit_pgm);
}
/****************************************************************/
/* Set the receiver variable to point to the next exit program */
/* that is returned. */
/****************************************************************/
rsl_ok=1;
rcv_ptr=rcv_var +
((Qus_EXTI0200_Entry_t *)rcv_ptr)>Offset_Next_Entry;
}
}
/********************************************************************/
/* */
/* main */
/* */
/********************************************************************/
void main()
{
int sel_criteria=0,
len_rcv_variable=3500,
exit_pgm_num=-1;
char continuation_hdl[16],
rcv_variable[3500],
*rcv_ptr;
error_code_struct error_code;
/******************************************************************/
/* Retrieve the exit point information first. If the current */
/* number of exit programs is not zero, retrieve the exit */
/* programs. It is not necessary to call for the exit point */
/* information to determine if the exit point has any exit */
/* programs. It is done here for illustration purposes only. */
/* You can make one call to the API for the exit program */
/* information and check the number of exit program entries */
/* returned field to see if there are any exit programs to call. */
/******************************************************************/
/******************************************************************/
/* Initialize the error code to inform the API that all */
/* exceptions should be returned through the error code parameter.*/
/******************************************************************/
error_code.ec_fields.Bytes_Provided=sizeof(error_code_struct);
/******************************************************************/
/* Blank out the continuation handle to let the API know that this*/
/* is a first attempt at the retrieve operation. */
/******************************************************************/
memset(continuation_hdl,' ',16);
/******************************************************************/
/* Call the API to retrieve the exit point information. */
/******************************************************************/
QusRetrieveExitInformation(continuation_hdl,
&rcv_variable,
len_rcv_variable,
"EXTI0100",
"EXAMPLE_EXIT_POINT ",
"EXMP0100",
exit_pgm_num,
&sel_criteria,
&error_code);
/******************************************************************/
/* If an exception occurs, the API returns the exception in the */
/* error code parameter. The bytes available field is set to */
/* zero if no exception occurs and nonzero if an exception does */
/* occur. */
/******************************************************************/
if (error_code.ec_fields.Bytes_Available != 0)
{
printf("ATTEMPT TO RETRIEVE INFORMATION FAILED WITH EXCEPTION: %.7s",
error_code.ec_fields.Exception_Id);
exit(1);
}
/******************************************************************/
/* If the call to retrieve exit point information is successful, */
/* check to see if there are any exit programs to call. */
/******************************************************************/
rcv_ptr=rcv_variable;
rcv_ptr += ((Qus_EXTI0100_t *)rcv_ptr)->Offset_Exit_Point_Entry;
if (((Qus_EXTI0100_Entry_t *)rcv_ptr)->Number_Exit_Programs != 0)
{
/*****************************************************************/
/* Blank out the continuation handle to let the API know that */
/* this is a first attempt at the retrieve operation. */
/*****************************************************************/
memset(continuation_hdl,' ',16);
/*****************************************************************/
/* Call the API to retrieve the exit program information. */
/*****************************************************************/
QusRetrieveExitInformation(continuation_hdl,
&rcv_variable,
len_rcv_variable,
"EXTI0200",
"EXAMPLE_EXIT_POINT ",
"EXMP0100",
exit_pgm_num,
&sel_criteria,
&error_code);
/*****************************************************************/
/* Verify that the call to the API is successful. */
/*****************************************************************/
if (error_code.ec_fields.Bytes_Available != 0)
{
printf("ATTEMPT TO RETRIEVE EXIT PROGRAMS FAILED WITH EXCEPTION:\
%.7s", error_code.ec_fields.Exception_Id);
exit(1);
}
/*****************************************************************/
/* If the call is successful, call the exit programs. */
/*****************************************************************/
Call_Exit_Program(rcv_variable);
/*****************************************************************/
/* If the continuation handle field in the receiver variable is */
/* not set to blanks, the API has more information to return */
/* than what could fit in the receiver variable. */
/*****************************************************************/
rcv_ptr=rcv_variable;
while (memcmp(((Qus_EXTI0200_t *)rcv_ptr)->Continue_Handle,
" ",16)!=0)
{
memcpy(continuation_hdl,
((Qus_EXTI0200_t *)rcv_ptr)>Continue_Handle,16);
/***************************************************************/
/* Call the API to retrieve the exit program information. */
/***************************************************************/
QusRetrieveExitInformation(continuation_hdl,
&rcv_variable,
len_rcv_variable,
"EXTI0200",
"EXAMPLE_EXIT_POINT ",
"EXMP0100",
exit_pgm_num,
&sel_criteria,
&error_code);
/***************************************************************/
/* Verify that the call to the API is successful. */
/***************************************************************/
if (error_code.ec_fields.Bytes_Available != 0)
{
printf("RETRIEVE EXIT PROGRAMS FAILED WITH EXCEPTION: %.7s",
error_code.ec_fields.Exception_Id);
exit(1);
}
/***************************************************************/
/* If the call is successful, call the exit programs. */
/* The receiver variable offers enough room for a minimum of */
/* one exit program entry because the receiver variable was */
/* declared as 3500 bytes. Therefore, this example only */
/* checks the number of exit programs returned field. If the */
/* receiver variable were not large enough to hold at least */
/* one entry, the bytes available field would need to be */
/* checked as well as the number of exit programs returned */
/* field. If the number of exit programs returned field is */
/* set to zero and the bytes available field is greater than */
/* the bytes returned field, the API had at least one exit */
/* program entry to return but was unable to because the */
/* receiver variable was too small. */
/***************************************************************/
Call_Exit_Program(rcv_variable);
} /* While continuation handle not set to blanks */
} /* Number of exit programs not equal to zero */
} /* End program */