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