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. The Retrieve Exit Information API returns a continuation handle when it has more information to return than what fits in the receiver variable.
/********************************************************************/ /* 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 */