CEE3GRC—Get the enclave return code

CEE3GRC retrieves the current value of the user enclave return code. Use CEE3GRC in conjunction with CEE3SRC to get and then set user enclave return codes.
Read syntax diagramSkip visual syntax diagram
Syntax

>>-CEE3GRC--(--return_code--,--fc--)---------------------------><

return_code (output)
The enclave return code.
fc (output)
A 12-byte feedback code, optional in some languages, that indicates the result of this service. If you choose to omit this parameter, refer to Invoking callable services for the appropriate syntax to indicate that the feedback code was omitted.

The following symbolic conditions can result from this service:

Code Severity Message number Message text
CEE000 0 The service completed successfully.

Usage notes

  • z/OS UNIX consideration—CEE3GRC is not supported in multithread applications.
  • PL/I MTF consideration—CEE3GRC is not supported in PL/I MTF applications.
  • PL/I consideration—When running PL/I with POSIX(ON), CEE3GRC is not supported.

For more information

Examples

  1. Following is an example of a C/C++ main() routine that ralls CEEHDLR and CEE3GRC.
    /*Module/File Name: EDC3GRC   */
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <leawi.h>
    #include <ceeedcct.h>
    
     /*****************************************************/
     /**                                                  */
     /** Function: CEEHDLR - Register user condition      */
     /**                     handler                      */
     /**         : CEE3GRC - Get enclave return code      */
     /*                                                   */
     /* 1. Register the user-written condition handler    */
     /*    CESETRC.                                       */
     /* 2. Call CERCDIV, which performs a divide-by-zero. */
     /* 3. CESETRC is entered, sets the enclave return    */
     /*    code to 999998 and resumes.                    */
     /* 4. The main routine regains control and           */
     /*    retrieves the enclave return code              */
     /*****************************************************/
    
    void CERCDIV(int);
     /*****************************************************
       Declaration of user-written condition handler
      *****************************************************/
    #ifdef __cplusplus
       extern "C" {
    #endif
       void CESETRC(_FEEDBACK *, _INT4*, _INT4 *, _FEEDBACK *);
    #ifdef __cplusplus
       }
    #endif
    
    main()
    {
     _INT4 idivisor = 0;
     _INT4 enclave_RC;
     _FEEDBACK feedback, new_feedback;
     _ENTRY pgmptr;
     _INT4 token;
    
     /*****************************************************
      The condition handler CESETRC is registered
      *****************************************************/
     pgmptr.address = (_POINTER)&CESETRC;;
     pgmptr.nesting = NULL;
     token = 97;
     CEEHDLR(&pgmptr, &token, &feedback);
    
     /*****************************************************
      A divide-by-zero is accomplished by calling CERCDIV.
      *****************************************************/
     CERCDIV(idivisor);   /* this causes a zero divide    */
    
     /*****************************************************
      Call CEE3GRC and check that enclave return code was set.
      *****************************************************/
     CEE3GRC(&enclave_RC, &feedback);
       if ( _FBCHECK ( feedback , CEE000 ) != 0 ) {
          printf("CEE3GRC failed with message number %d\n",
                 feedback.tok_msgno);
          exit(2999);
       }
    
     if (enclave_RC != 999998)
       printf ("Error setting enclave return code");
    }
  2. Following is an example of a C/C++ user-written condition handler that sets a user enclave return code.
    /*Module/File Name: EDC3SRC   */
     /*****************************************************/
     /**                                                  */
     /** Function: CEE3SRC - Set the enclave return code. */
     /*                                                   */
     /* This is the user-written condition handler        */
     /* registered by CEGETRC. It invokes CEE3SRC to set  */
     /* the enclave return code to 999998                 */
     /* when a divide-by-zero condition is encountered.   */
     /**                                                  */
     /*****************************************************/
    #include <stdio.h>
    #include <string.h>
    #include <leawi.h>
    #include <ceeedcct.h>
    #define RESUME 10
    #define PERCOLATE 20
     /*****************************************************/
    
    #ifdef __cplusplus
     extern "C" void CESETRC (_FEEDBACK *, _INT4 *,
     _INT4 *, _FEEDBACK *);
    #endif
    
    void CESETRC (_FEEDBACK *cond, _INT4 *input_token,
                   _INT4 *result, _FEEDBACK *new_cond)
    {
     _INT4 enclave_RC;
     _FEEDBACK feedback;
    
     if ( _FBCHECK ( *cond , CEE349 ) == 0 )
      {
       enclave_RC = 999998;
       CEE3SRC(&enclave_RC, &feedback);
       *result = RESUME;
      }
     else
      {
       *result = PERCOLATE;
      }
    }
  3. Following is an example of a C/C++ subroutine that generates the divide-by-zero condition.
    /*Module/File Name: EDCDIV    */
    #include <stdio.h>
    #include <string.h>
     /**************************************************/
     /**                                               */
     /* This is a divide-by-zero routine. It divides   */
     /* an input integer by a constant.                */
     /**                                               */
     /**************************************************/
    
    void CERCDIV (int Integer)
    
    {
     int num;
     num = 1/Integer;
    }
  4. Following is an example of a COBOL main routine that calls CEEHDLR and CEE3GRC.
    CBL LIB,QUOTE,C,RENT,OPTIMIZE,NODYNAM
          *Module/File Name: IGZT3GRC
          **************************************************
          **                                              **
          ** CBL2GRC - Call the following Lang. Env. svcs: **
          **                                              **
          **         : CEEHDLR - register user condition  **
          **                     handler                  **
          **         : CEE3GRC - get enclave return code  **
          **                                              **
          ** 1. Registers user condition handler CESETRC. **
          ** 2. Program then calls CERCDIV which performs **
          **    a divide by zero operation.               **
          ** 3. CESETRC gets control and set the enclave  **
          **    return code to 999998 and resumes.        **
          ** 4. Regains control and retrieves the enclave **
          **    return code.                              **
          **************************************************
           IDENTIFICATION DIVISION.
           PROGRAM-ID.    CBL3GRC.
    
           DATA DIVISION.
           WORKING-STORAGE SECTION.
           01  TOKEN           PIC X(4).
           01  IDIVISOR        PIC S9(9)
                               BINARY VALUE ZERO.
           01  ENCLAVE-RC      PIC S9(9) BINARY.
          **
          **  Declares for condition handling
          **
           01  PGMPTR          USAGE IS PROCEDURE-POINTER.
           01  FBCODE.
               02  Condition-Token-Value.
               COPY  CEEIGZCT.
                   03  Case-1-Condition-ID.
                       04  Severity    PIC S9(4) BINARY.
                       04  Msg-No      PIC S9(4) BINARY.
                   03  Case-2-Condition-ID
                             REDEFINES Case-1-Condition-ID.
                       04  Class-Code  PIC S9(4) BINARY.
                       04  Cause-Code  PIC S9(4) BINARY.
                   03  Case-Sev-Ctl    PIC X.
                   03  Facility-ID     PIC XXX.
               02  I-S-Info            PIC S9(9) BINARY.
    
           PROCEDURE DIVISION.
    
           0001-BEGIN-PROCESSING.
          *************************************************
          ** Register user condition handler CESETRC using
          **     CEEHDLR
          *************************************************
               SET PGMPTR TO ENTRY  "CESETRC".
               MOVE 97 TO TOKEN
               CALL "CEEHDLR" USING PGMPTR, TOKEN, FBCODE.
               IF NOT CEE000 of FBCODE  THEN
                   DISPLAY "CEEHDLR failed with msg "
                       Msg-No of FBCODE UPON CONSOLE
                   STOP RUN
               END-IF.
    
          *************************************************
          ** Call CERCDIV  to cause a divide by zero
          **     condition
          *************************************************
               CALL "CERCDIV" USING IDIVISOR.
          *************************************************
          ** Call CEE3GRC  to get the enclave return code
          *************************************************
               CALL "CEE3GRC" USING ENCLAVE-RC, FBCODE.
               IF NOT CEE000 of FBCODE  THEN
                   DISPLAY "CEEHDLR failed with msg "
                       Msg-No of FBCODE UPON CONSOLE
                   STOP RUN
               END-IF.
    
               IF (ENCLAVE-RC =  999998) THEN
                   DISPLAY "Enclave return code "
                       "set and retrieved."
               ELSE
                   DISPLAY "*** Unexpected enclave return "
                       "code of " ENCLAVE-RC " encountered"
               END-IF.
    
               GOBACK.
           End program CBL3GRC.
  5. Following is an example of a COBOL condition handler that sets a user enclave return code and resumes when a divide-by-zero condition occurs.
       CBL C,RENT,OPTIMIZE,NODYNAM,LIB,QUOTE
          *Module/File Name: IGZT3SRC
          *************************************************
          **                                             **
          ** DRV3SRC - Drive sample program for CEE3SRC. **
          **                                             **
          *************************************************
           IDENTIFICATION DIVISION.
           PROGRAM-ID. DRV3SRC.
    
           DATA DIVISION.
           WORKING-STORAGE SECTION.
           01  ROUTINE         PROCEDURE-POINTER.
           01  DENOMINATOR     PIC S9(9) BINARY.
           01  NUMERATOR       PIC S9(9) BINARY.
           01  RATIO           PIC S9(9) BINARY.
           01  TOKEN           PIC S9(9) BINARY VALUE 0.
           01  FC.
               02  Condition-Token-Value.
               COPY  CEEIGZCT.
                   03  Case-1-Condition-ID.
                       04  Severity    PIC S9(4) BINARY.
                       04  Msg-No      PIC S9(4) BINARY.
                   03  Case-2-Condition-ID
                             REDEFINES Case-1-Condition-ID.
                       04  Class-Code  PIC S9(4) BINARY.
                       04  Cause-Code  PIC S9(4) BINARY.
                   03  Case-Sev-Ctl    PIC X.
                   03  Facility-ID     PIC XXX.
               02  I-S-Info            PIC S9(9) BINARY.
    
           PROCEDURE DIVISION.
    
           REGISTER-HANDLER.
          *************************************************
          ** Register handler
          *************************************************
               SET ROUTINE TO ENTRY "CBL3SRC".
               CALL "CEEHDLR" USING ROUTINE, TOKEN, FC.
               IF  NOT CEE000 of FC  THEN
                   DISPLAY "CEEHDLR failed with msg "
                       Msg-No of FC UPON CONSOLE
                   STOP RUN
               END-IF.   RAISE-CONDITION.
          *************************************************
          ** Cause a zero-divide condition.
          *************************************************
               MOVE 0 TO DENOMINATOR.
               MOVE 1 TO NUMERATOR.
               DIVIDE NUMERATOR BY DENOMINATOR
                      GIVING RATIO.
    
          UNREGISTER-HANDLER.
          *************************************************
          ** UNregister handler
          *************************************************
               CALL "CEEHDLU" USING ROUTINE, TOKEN, FC.
               IF NOT CEE000 of FC  THEN
                   DISPLAY "CEEHDLU failed with msg "
                       Msg-No of FC UPON CONSOLE
               END-IF.
    
               STOP RUN.
           END PROGRAM DRV3SRC.
    
          ************************************************
          **                                            **
          ** CBL3SRC - Call CEE3SRC to set the enclave  **
          **                     return code            **
          **                                            **
          ** This is an example of a user-written       **
          ** condition handler that sets a user         **
          ** enclave return code and resumes when       **
          ** a divide-by-zero condition occurs.         **
          ************************************************
           IDENTIFICATION DIVISION.
           PROGRAM-ID. CBL3SRC.
    
           DATA DIVISION.
    
           WORKING-STORAGE SECTION.
           01  ENCLAVE-RC              PIC S9(9) BINARY.
           01  FEEDBACK.
               02  Condition-Token-Value.
               COPY  CEEIGZCT.
                   03  Case-1-Condition-ID.
                       04  Severity    PIC S9(4) BINARY.
                       04  Msg-No      PIC S9(4) BINARY.
                   03  Case-2-Condition-ID
                             REDEFINES Case-1-Condition-ID.
                       04  Class-Code  PIC S9(4) BINARY.
                       04  Cause-Code  PIC S9(4) BINARY.
                   03  Case-Sev-Ctl    PIC X.
                   03  Facility-ID     PIC XXX.
               02  I-S-Info            PIC S9(9) BINARY.
          LINKAGE SECTION.
           01  TOKEN                   PIC X(4).
           01  RESULT-CODE             PIC S9(9) BINARY.
               88 RESUME               VALUE +10.
               88 PERCOLATE            VALUE +20.
           01  CURRENT-CONDITION.
               02  Condition-Token-Value.
                COPY  CEEIGZCT.
                   03  Case-1-Condition-ID.
                       04  Severity    PIC S9(4) BINARY.
                       04  Msg-No      PIC S9(4) BINARY.
                   03  Case-2-Condition-ID
                             REDEFINES Case-1-Condition-ID.
                       04  Class-Code  PIC S9(4) BINARY.
                       04  Cause-Code  PIC S9(4) BINARY.               
    03  Case-Sev-Ctl    PIC X.
                   03  Facility-ID     PIC XXX.
               02  I-S-Info            PIC S9(9) BINARY.
           01  NEW-CONDITION.
               02  Condition-Token-Value.
               COPY  CEEIGZCT.
                   03  Case-1-Condition-ID.
                       04  Severity    PIC S9(4) BINARY.
                       04  Msg-No      PIC S9(4) BINARY.
                   03  Case-2-Condition-ID
                             REDEFINES Case-1-Condition-ID.
                       04  Class-Code  PIC S9(4) BINARY.
                       04  Cause-Code  PIC S9(4) BINARY.
                   03  Case-Sev-Ctl    PIC X.
                   03  Facility-ID     PIC XXX.
               02  I-S-Info            PIC S9(9) BINARY.
    
           PROCEDURE DIVISION USING CURRENT-CONDITION,
                                    TOKEN, RESULT-CODE,
                                    NEW-CONDITION.
    
           HANDLE-CONDITION.
          *************************************************
          ** Check for divide-by-zero condition (CEE349)
          *************************************************
               IF CEE349 of CURRENT-CONDITION  THEN
                   MOVE 761 TO ENCLAVE-RC
                   CALL "CEE3SRC" USING ENCLAVE-RC,
                                        FEEDBACK
                   IF NOT CEE000 of FEEDBACK  THEN
                       DISPLAY "CEE3SRC failed with msg "
                           Msg-No of FEEDBACK UPON CONSOLE
                   END-IF
               END-IF.
               SET PERCOLATE TO TRUE
    
               GOBACK.
    
           END PROGRAM CBL3SRC.
  6. Following is an example of a COBOL subroutine that generates a divide-by-zero condition.
    CBL LIB,QUOTE,C,RENT,OPTIMIZE,NODYNAM
          *Module/File Name: IGZTDIV
          ************************************************
          **                                            **
          **Function       :                            **
          **                                            **
          **     A divide by zero is attempted. This    **
          **  induces the invocation of user condition  **
          **  handler CESETRC registered in program     **
          **  CEGETRC.                                  **
          **               :                            **
          ************************************************
           IDENTIFICATION DIVISION.
           PROGRAM-ID.   CERCDIV.
    
           DATA DIVISION.
           WORKING-STORAGE SECTION.
           01  TO-DIVIDE        PIC S9(9) BINARY VALUE 1.
           LINKAGE SECTION.
           01  IDIVISOR         PIC S9(9) BINARY.
    
           PROCEDURE DIVISION USING IDIVISOR.
    
          ************************************************
          **  divide a constant by IDIVISOR.            **
          ************************************************
               DIVIDE IDIVISOR INTO TO-DIVIDE.
    
               GOBACK.
           End program CERCDIV.
  7. Following is an example in PL/I that sets and retrieves the user enclave return code when a divide-by-zero is generated.
    *Process lc(101),opt(0),s,map,list,stmt,a(f),ag,macro ;
     /*Module/File Name: IBMDIV                          */
     /****************************************************/
     /**                                                 */
     /** Function: CEE3SRC - Set the enclave return code */
     /**         : CEE3GRC - Get the enclave return code */
     /*                                                  */
     /* 1. A user ZERODIVIDE ON-unit is established by   */
     /*    CESETRC.                                      */
     /* 2. A sub-program, sdivide, is called and causes  */
     /*    a ZERODIVIDE condition to occur.              */
     /* 3. The ON-unit for ZERODIVIDE is entered.        */
     /*    The ON-unit calls CEE3GRC to get the current  */
     /*    enclave return code. It increments the return */
     /*    code by 4444, and sets the enclave return     */
     /*    code to this new value.                       */
     /* 4. On completion, the program prints the enclave */
     /*    return code.                                  */
     /****************************************************/
     CESETRC: Proc Options(Main)        ;
    
        %INCLUDE  CEEIBMAW;
        %INCLUDE  CEEIBMCT;
                     REAL FIXED BINARY(31,0);  
        DCL Enclave_RC REAL FIXED BINARY(31,0);
        DCL 01 FC,                     /* Feedback token */
               03 MsgSev    REAL FIXED BINARY(15,0),
               03 MsgNo     REAL FIXED BINARY(15,0),
               03 Flags,
                  05 Case      BIT(2),
                  05 Severity  BIT(3),
                  05 Control   BIT(3),
               03 FacID     CHAR(3),    /* Facility ID */
               03 ISI   /* Instance-Specific Information */
           
     /****************************************************/
     /* A ZERODIVIDE ON-unit is established              */
     /****************************************************/
        on zerodivide begin;
           call CEE3GRC (Enclave_RC, fc);
           IF  FBCHECK( FC, CEE000)  THEN  DO;
              PUT SKIP LIST( 'Original Enclave RC was '
                 || Enclave_RC );
              END;
           ELSE  DO;
              DISPLAY( 'CEE3GRC failed with msg '
                 || FC.MsgNo );
              STOP;
              END;
           Enclave_RC = Enclave_RC + 4444;
           call CEE3SRC (Enclave_RC, fc);
           IF  FBCHECK( FC, CEE000)  THEN  DO;
              PUT SKIP LIST( 'New Enclave RC is '
                 || Enclave_RC );
              END;
           ELSE  DO;
              DISPLAY( 'CEE3SRC failed with msg '
                 || FC.MsgNo );
              STOP;
              END;
           goto resume;
        end;
     /****************************************************/
     /* Call sdivide to cause a ZERODIVIDE condition.    */
     /****************************************************/
        call sdivide;
     resume:
        put skip edit('Enclave return code is ',
              Enclave_RC)  (A, F(10));
    
     /****************************************************/
     /* The sdivide routine causes a ZERODIVIDE condition*/
     /****************************************************/
     sdivide: proc;
        dcl int fixed bin (15,0);
        dcl int_2 fixed bin (15,0) init(5);
        dcl int_3 fixed bin (15,0) init(0);
        int = int_2 / int_3;
     end sdivide;
    
     End cesetrc;