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.
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
- See CEE3SRC—Set the enclave return code for more information about the CEE3SRC callable service.
- See z/OS Language Environment Programming Guide for more information about the CEE3GRC and CEE3SRC callable services.
Examples
- 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"); }
- 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; } }
- 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; }
- 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.
- 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.
- 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.
- 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;