Rexx Exits Interface

The Rexx system exits let the programmer create a customized Rexx operating environment. You can set up user-defined exit handlers to process specific Rexx activities.

Applications can create exits for:

Direct exit handlers are specified when the interpreter instance is created, and reside as entry points within the application that creates the interpreter instance.

Writing Context Exit Handlers

The following is a sample exit handler declaration:

int REXXENTRY Rexx_IO_exit(
     RexxExitContext *context,   // the exit context API vector
     int   exitNumber,           // code defining the exit function
     int   subfunction,          // code defining the exit subfunction
     PEXIT parmBlock);           // function-dependent control block

where:

context

is the RexxExitContext vector that provides access to interpreter services for this exit handler.

exitNumber

is the major function code defining the type of exit call.

subfunction

is the subfunction code defining the exit event for the call.

parmBlock

is a pointer to the exit parameter list.

The exit parameter list contains exit-specific information. See the exit descriptions following the parameter list formats.

Note: Some exit subfunctions do not have parameters. parmBlock is set to NULL for exit subfunctions without parameters.

Exit Return Codes

Exit handlers return an integer value that signals one of the following actions:

RXEXIT_HANDLED

The exit handler processed the exit subfunction and updated the subfunction parameter list as required. The Rexx interpreter continues with processing as usual.

RXEXIT_NOT_HANDLED

The exit handler did not process the exit subfunction. The Rexx interpreter processes the subfunction as if the exit handler were not called.

RXEXIT_RAISE_ERROR

A fatal error occurred in the exit handler. The Rexx interpreter raises Rexx error 48 ("Failure in system service"). Other errors can be raised using the RaiseException() API provided by the exit context.

For example, if an application creates an input/output exit handler, one of the following happens:

  • When the exit handler returns RXEXIT_NOT_HANDLED for an RXSIOSAY subfunction, the Rexx interpreter writes the output line to STDOUT.

  • When the exit handler returns RXEXIT_HANDLED for an RXSIOSAY subfunction, the Rexx interpreter assumes the exit handler has handled all required output. The interpreter does not write the output line to STDOUT.

  • When the exit handler returns RXEXIT_RAISE_ERROR for an RXSIOSAY subfunction, the interpreter raises Rexx error 48, "Failure in system service".

Exit Parameters

Each exit subfunction has a different parameter list. All RXSTRING exit subfunction parameters are passed as null-terminated strings. The terminating null is not included in the length stored in the RXSTRING structures. The string values pointed to by the RXSTRING structs may also contain null characters.

For some exit subfunctions, the exit handler can return an RXSTRING character result in the parameter list. The interpreter provides a default 256-byte RXSTRING for the result string. If the result is longer than 256 bytes, a new RXSTRING can be allocated using RexxAllocateMemory(size). The Rexx interpreter will release the allocated storage after the exit handler returns.

Identifying Exit Handlers to Rexx

System exit handlers are specified using the DIRECT_EXITS option when the interpreter instance is created. The exits are specified using a RexxContextExit structure identifying which exits will be enabled.

Context Exit Definitions

The Rexx interpreter supports the following system exits:

RXFNC

External function call exit.

RXFNCCAL

Call an external function. This exit is called at the beginning of the search for external functions, allowing external functions calls to be intercepted. The RXFNCCAL converts all function arguments to RXSTRING values and can only return RXSTRING values as a function result. For full object access, the RXOFNC exit is also provided.

RXOFNC

Object oriented external function call exit.

RXOFNCCAL

Call an external function. This exit is called at the beginning of the search for external functions, allowing external functions calls to be intercepted. This is an extended version of the RXFNC exit that passes arguments as object references and allows object return values.

RXEXF

Scripting external function call exit.

RXEXFCAL

Call an external function. This exit is called at the end of the search for external functions if no suitable call target has been found. This allows applications to extend the external function search order. Like the RXOFNC exit, the RXEXF exit will pass function arguments and return values as Rexx objects.

RXCMD

Subcommand call exit.

RXCMDHST

Call a subcommand handler.

RXMSQ

External data queue exit.

RXMSQPLL

Pull a line from the external data queue.

RXMSQPSH

Place a line in the external data queue.

RXMSQSIZ

Return the number of lines in the external data queue.

RXMSQNAM

Set the active external data queue name.

RXSIO

Standard input and output exit.

RXSIOSAY

Write a line to the standard output stream for the SAY instruction.

RXSIOTRC

Write a line to the standard error stream for the Rexx trace or Rexx error messages.

RXSIOTRD

Read a line from the standard input stream for PULL or PARSE PULL.

RXSIODTR

Read a line from the standard input stream for interactive debugging.

RXNOVAL

NOVALUE exit.

RXNOVALCALL

Process a variable NOVALUE condition.

RXVALUE

VALUE built-in function extension.

RXVALUECALL

Process a VALUE() built-in function call for an unknown named environment.

RXHLT

Halt processing exit.

RXHLTTST

Test for a HALT condition.

RXHLTCLR

Clear a HALT condition.

RXTRC

External trace exit.

RXTRCTST

Test for an external trace event.

RXINI

Initialization exit.

RXINIEXT

Allow additional Rexx procedure initialization.

RXTER

Termination exit.

RXTEREXT

Process Rexx procedure termination.

The following sections describe each exit subfunction, including:

RXOFNC

Processes calls to external functions.

RXOFNCCAL

Processes calls to external functions.

  • When called: At beginning of the search for an external routine or function.

  • Default action: Call the external routine using the usual external function search order.

  • Exit action: Call the external routine, if possible.

  • Continuation: If necessary, raise Rexx error 40 ("Incorrect call to routine"), 43 ("Routine not found"), or 44 ("Function or message did not return data").

  • Parameter list:

    
typedef  struct _RXOFNC_FLAGS {        /* fl */
       unsigned rxfferr  : 1;              /* Invalid call to routine.   */
       unsigned rxffnfnd : 1;              /* Function not found.        */
       unsigned rxffsub  : 1;              /* Called as a subroutine     */
    }  RXOFNC_FLAGS ;
    
    typedef  struct _RXOFNCCAL_PARM {      /* fnc */
       RXOFNC_FLAGS      rxfnc_flags ;     /* function flags             */
       CONSTRXSTRING     rxfnc_name;       // the called function name
       size_t            rxfnc_argc;       /* Number of args in list.    */
       RexxObjectPtr    *rxfnc_argv;       /* Pointer to argument list.  */
       RexxObjectPtr     rxfnc_retc;       /* Return value.              */
    }  RXOFNCCAL_PARM;

    The name of the external function is defined by the rxfnc_name CONSTRXSTRING value. The arguments to the function are in rxfnc_argv array and rxfnc_argc gives the number of arguments. If you call the named external function with the Rexx CALL instruction (rather than using a function call), the flag rxffsub is TRUE.

    The exit handler can set rxfnc_flags to indicate whether the external function call was successful. If neither rxfferr nor rxffnfnd is TRUE, the exit handler successfully called the external function. The error flags are checked only when the exit handler handles the request.

    The exit handler sets rxffnfnd to TRUE when the exit handler cannot locate the external function. The interpreter raises Rexx error 43, "Routine not found". The exit handler sets rxfferr to TRUE when the exit handler locates the external function, but the external function returned an error return code. The Rexx interpreter raises error 40, "Incorrect call to routine."

    The exit handler returns the external function result in the rxfnc_retc RexxObjectPtr. The Rexx interpreter raises error 44, "Function or method did not return data," when the external routine is called as a function and the exit handler does not return a result. When the external routine is called with the Rexx CALL instruction, a result is not required.

RXEXF

Processes calls to external functions.

RXEXFCAL

Processes calls to external functions.

  • When called: At end of the search for an external routine or function when no suitable call target has been located.

  • Default action: Raise error 43 ("Routine not found").

  • Exit action: Call the external routine, if possible.

  • Continuation: If necessary, raise Rexx error 40 ("Incorrect call to routine"), 43 ("Routine not found"), or 44 ("Function or message did not return data").

  • Parameter list:

    
typedef  struct _RXEXF_FLAGS {         /* fl */
       unsigned rxfferr  : 1;              /* Invalid call to routine.   */
       unsigned rxffnfnd : 1;              /* Function not found.        */
       unsigned rxffsub  : 1;              /* Called as a subroutine     */
    }  RXEXT_FLAGS ;
    
    typedef  struct _RXEXFCAL_PARM {       /* fnc */
       RXEXF_FLAGS       rxfnc_flags ;     /* function flags             */
       CONSTRXSTRING     rxfnc_name;       // the called function name
       size_t            rxfnc_argc;       /* Number of args in list.    */
       RexxObjectPtr    *rxfnc_argv;       /* Pointer to argument list.  */
       RexxObjectPtr     rxfnc_retc;       /* Return value.              */
    }  RXEXFCAL_PARM;

    The name of the external function is defined by the rxfnc_name CONSTRXSTRING value. The arguments to the function are in rxfnc_argv array and rxfnc_argc gives the number of arguments. If you call the named external function with the Rexx CALL instruction (rather than using a function call), the flag rxffsub is TRUE.

    The exit handler can set rxfnc_flags to indicate whether the external function call was successful. If neither rxfferr nor rxffnfnd is TRUE, the exit handler successfully called the external function. The error flags are checked only when the exit handler handles the request.

    The exit handler sets rxffnfnd to TRUE when the exit handler cannot locate the external function. The interpreter raises Rexx error 43, "Routine not found". The exit handler sets rxfferr to TRUE when the exit handler locates the external function, but the external function returned an error return code. The Rexx interpreter raises error 40, "Incorrect call to routine."

    The exit handler returns the external function result in the rxfnc_retc RexxObjectPtr. The Rexx interpreter raises error 44, "Function or method did not return data," when the external routine is called as a function and the exit handler does not return a result. When the external routine is called with the Rexx CALL instruction, a result is not required.

RXFNC

Processes calls to external functions.

RXFNCCAL

Processes calls to external functions.

  • When called: At beginning of the search for an external routine or function.

  • Default action: Call the external routine using the usual external function search order.

  • Exit action: Call the external routine, if possible.

  • Continuation: If necessary, raise Rexx error 40 ("Incorrect call to routine"), 43 ("Routine not found"), or 44 ("Function or message did not return data").

  • Parameter list:

    typedef struct {
       struct {
          unsigned rxfferr  : 1;           /* Invalid call to routine.    */
          unsigned rxffnfnd : 1;           /* Function not found.         */
          unsigned rxffsub  : 1;           /* Called as a subroutine if   */
                                           /* TRUE.  Return values are    */
                                           /* optional for subroutines,   */
                                           /* required for functions.     */
       } rxfnc_flags ;
    
       const char *      rxfnc_name;       /* Pointer to function name.   */
       unsigned short    rxfnc_namel;      /* Length of function name.    */
       const char *      rxfnc_que;        /* Current queue name.         */
       unsigned short    rxfnc_quel;       /* Length of queue name.       */
       unsigned short    rxfnc_argc;       /* Number of args in list.     */
       PCONSTRXSTRING    rxfnc_argv;       /* Pointer to argument list.   */
                                           /* List mimics argv list for   */
                                           /* function calls, an array of */
                                           /* RXSTRINGs.                  */
       RXSTRING          rxfnc_retc;       /* Return value.               */
    } RXFNCCAL_PARM;

    The name of the external function is defined by rxfnc_name and rxfnc_namel. The arguments to the function are in rxfnc_argc and rxfnc_argv. If you call the named external function with the Rexx CALL instruction (rather than using a function call), the flag rxffsub is TRUE.

    The exit handler can set rxfnc_flags to indicate whether the external function call was successful. If neither rxfferr nor rxffnfnd is TRUE, the exit handler successfully called the external function. The error flags are checked only when the exit handler handles the request.

    The exit handler sets rxffnfnd to TRUE when the exit handler cannot locate the external function. The interpreter raises Rexx error 43, "Routine not found". The exit handler sets rxfferr to TRUE when the exit handler locates the external function, but the external function returned an error return code. The Rexx interpreter raises error 40, "Incorrect call to routine."

    The exit handler returns the external function result in the rxfnc_retc RXSTRING. The Rexx interpreter raises error 44, "Function or method did not return data," when the external routine is called as a function and the exit handler does not return a result. When the external routine is called with the Rexx CALL instruction, a result is not required.

    The RXFNC translates all call arguments to string values and only allows a string value as a return value. To access call arguments as Rexx objects, use the RXOFNC exit.

RXCMD

Processes calls to subcommand handlers.

RXCMDHST

Calls a named subcommand handler.

  • When called: When Rexx procedure issues a command.

  • Default action: Call the named subcommand handler specified by the current Rexx ADDRESS setting.

  • Exit action: Process the call to a named subcommand handler.

  • Continuation: Raise the ERROR or FAILURE condition when indicated by the parameter list flags.

  • Parameter list:

    typedef struct {
       struct {                            /* Condition flags             */
          unsigned rxfcfail : 1;           /* Command failed.  Trap with  */
                                           /* CALL or SIGNAL on FAILURE.  */
          unsigned rxfcerr  : 1;           /* Command ERROR occurred.     */
                                           /* Trap with CALL or SIGNAL on */
                                           /* ERROR.                      */
       } rxcmd_flags;
       const char *      rxcmd_address;    /* Pointer to address name.    */
       unsigned short    rxcmd_addressl;   /* Length of address name.     */
       const char *      rxcmd_dll;        /* dll name for command.       */
       unsigned short    rxcmd_dll_len;    /* Length of dll name.  0 ==>  */
                                           /* executable file.            */
       CONSTRXSTRING     rxcmd_command;    /* The command string.         */
       RXSTRING          rxcmd_retc;       /* Pointer to return code      */
                                           /* buffer.  User allocated.    */
    } RXCMDHST_PARM;

    The rxcmd_command field contains the issued command. Rxcmd_address, rxcmd_addressl, rxcmd_dll, and rxcmd_dll_len fully define the current ADDRESS setting. Rxcmd_retc is an RXSTRING for the return code value assigned to Rexx special variable RC.

    The exit handler can set rxfcfail or rxfcerr to TRUE to raise an ERROR or FAILURE condition.

RXMSQ

External data queue exit.

RXMSQPLL

Pulls a line from the external data queue.

  • When called: When a Rexx PULL instruction, PARSE PULL instruction, or LINEIN built-in function reads a line from the external data queue.

  • Default action: Remove a line from the current Rexx data queue.

  • Exit action: Return a line from the data queue that the exit handler provided.

  • Parameter list:

    typedef struct {
       RXSTRING          rxmsq_retc;       /* Pointer to dequeued entry   */
                                           /* buffer.  User allocated.    */
    } RXMSQPLL_PARM;

    The exit handler returns the queue line in the rxmsq_retc RXSTRING.

RXMSQPSH

Places a line in the external data queue.

  • When called: When a Rexx PUSH instruction, QUEUE instruction, or LINEOUT built-in function adds a line to the data queue.

  • Default action: Add the line to the current Rexx data queue.

  • Exit action: Add the line to the data queue that the exit handler provided.

  • Parameter list:

    typedef struct {
       struct {                            /* Operation flag              */
          unsigned rxfmlifo : 1;           /* Stack entry LIFO when TRUE, */
                                           /* FIFO when FALSE.            */
       } rxmsq_flags;
       CONSTRXSTRING     rxmsq_value;      /* The entry to be pushed.     */
    } RXMSQPSH_PARM;

    The rxmsq_value RXSTRING contains the line added to the queue. It is the responsibility of the exit handler to truncate the string if the exit handler data queue has a maximum length restriction. Rxfmlifo is the stacking order (LIFO or FIFO).

RXMSQSIZ

Returns the number of lines in the external data queue.

  • When called: When the Rexx QUEUED built-in function requests the size of the external data queue.

  • Default action: Request the size of the current Rexx data queue.

  • Exit action: Return the size of the data queue that the exit handler provided.

  • Parameter list:

    typedef struct {
       size_t            rxmsq_size;       /* Number of Lines in Queue    */
    } RXMSQSIZ_PARM;

    The exit handler returns the number of queue lines in rxmsq_size.

RXMSQNAM

Sets the name of the active external data queue.

  • When called: Called by the RXQUEUE("SET", newname) built-in function.

  • Default action: Change the current default queue to newname.

  • Exit action: Change the default queue name for the data queue that the exit handler provided.

  • Parameter list:

    typedef struct {
       CONSTRXSTRING     rxmsq_name;       /* RXSTRING containing         */
                                           /* queue name.                 */
    } RXMSQNAM_PARM;

    rxmsq_name contains the new queue name.

RXSIO

Standard input and output.

Note: The PARSE LINEIN instruction and the LINEIN, LINEOUT, LINES, CHARIN, CHAROUT, and CHARS built-in functions do not call the RXSIO exit handler.

RXSIOSAY

Writes a line to the standard output stream.

  • When called: When the SAY instruction writes a line to the standard output stream.

  • Default action: Write a line to the standard output stream (STDOUT).

  • Exit action: Write a line to the output stream that the exit handler provided.

  • Parameter list:

    typedef struct {
       CONSTRXSTRING      rxsio_string;     /* String to display.          */
    } RXSIOSAY_PARM;

    The output line is contained in rxsio_string. The output line can be of any length. It is the responsibility of the exit handler to truncate or split the line if necessary.

RXSIOTRC

Writes trace and error message output to the standard error stream.

  • When called: To output lines of trace output and Rexx error messages.

  • Default action: Write a line to the standard error stream (.ERROR).

  • Exit action: Write a line to the error output stream that the exit handler provided.

  • Parameter list:

    typedef struct {
       CONSTRXSTRING       rxsio_string;     /* Trace line to display.      */
    } RXSIOTRC_PARM;

    The output line is contained in rxsio_string. The output line can be of any length. It is the responsibility of the exit handler to truncate or split the line if necessary.

RXSIOTRD

Reads from standard input stream.

  • When called: To read from the standard input stream for the Rexx PULL and PARSE PULL instructions.

  • Default action: Read a line from the standard input stream (STDIN).

  • Exit action: Return a line from the standard input stream that the exit handler provided.

  • Parameter list:

    typedef struct {
       RXSTRING          rxsiotrd_retc;    /* RXSTRING for input.         */
    } RXSIOTRD_PARM;

    The input stream line is returned in the rxsiotrd_retc RXSTRING.

RXSIODTR

Interactive debug input.

  • When called: To read from the debug input stream for interactive debug prompts.

  • Default action: Read a line from the standard input stream (STDIN).

  • Exit action: Return a line from the standard debug stream that the exit handler provided.

  • Parameter list:

    typedef struct {
       RXSTRING          rxsiodtr_retc;    /* RXSTRING for input.         */
    } RXSIODTR_PARM;

    The input stream line is returned in the rxsiodtr_retc RXSTRING.

RXNOVAL

Processes NOVALUE variable conditions.

RXNOVALCALL

Processes a Rexx NOVALUE condition.

  • When called: Before the interpreter raises a NOVALUE condition. The exit is given the opportunity to provide a value to the unassigned variable.

  • Default action: Raise a NOVALUE condition for an unassigned variable.

  • Exit action: Return an initial value for an unassigned variable.

  • Continuation: If the exit provides a value for the unassigned variable, that value is assigned to the indicated variable. The exit will not be called for the same variable on the next reference unless the variable is dropped. If a value is not returned, a NOVALUE condition will be raised. If SIGNAL ON NOVALUE is not enabled, the variable name will be returned as the value.

  • Parameter list:

    
typedef  struct _RXVARNOVALUE_PARM {   /* var */
       RexxStringObject  variable_name;    // the request variable name
       RexxObjectPtr     value;            // returned variable value
    }  RXVARNOVALUE_PARM;

RXVALUE

Extends the environments available to the VALUE() built-in function.

RXVALUECALL

Processes an extended call to the VALUE() built-in function.

  • When called: When the VALUE() built-in function is called with an unknown environment name. The exit is given the opportunity to provide a value for the given environment selector.

  • Default action: Raise a SYNTAX error for an unknown environment name.

  • Exit action: Return a value for the given name/environment pair.

  • Continuation: If the exit provides a value for the VALUE() call, that value is returned as a result. .

  • Parameter list:

    
typedef  struct _RXVALCALL_PARM {      /* val */
       RexxStringObject  selector;         // the environment selector name
       RexxStringObject  variable_name;    // the request variable name
       RexxObjectPtr     value;            // returned variable value
    }  RXVALCALL_PARM;

    If the newValue argument is specified on the VALUE() built-in function, that value is assigned to value on the call to the exit.

RXHLT

HALT condition processing.

Because the RXHLT exit handler is called after every Rexx instruction, enabling this exit slows Rexx program execution. The RexxSetHalt() function can halt a Rexx program without between-instruction polling.

RXHLTTST

Tests the HALT indicator.

  • When called: When the interpreter polls externally raises HALT conditions. The exit will be called after completion of every Rexx instruction.

  • Default action: The interpreter uses the system facilities for trapping Cntrl-Break signals.

  • Exit action: Return the current state of the HALT condition (either TRUE or FALSE).

  • Continuation: Raise the Rexx HALT condition if the exit handler returns TRUE.

  • Parameter list:

    typedef struct {
       struct {                            /* Halt flag                   */
          unsigned rxfhhalt : 1;           /* Set if HALT occurred.       */
       } rxhlt_flags;
    } RXHLTTST_PARM;

    If the exit handler sets rxfhhalt to TRUE, the HALT condition is raised in the Rexx program.

    The Rexx program can retrieve the reason string using the CONDITION("D") built-in function.

RXHLTCLR

Clears the HALT condition.

  • When called: When the interpreter has recognized and raised a HALT condition, to acknowledge processing of the HALT condition.

  • Default action: The interpreter resets the Cntrl-Break signal handlers.

  • Exit action: Reset exit handler HALT state to FALSE.

  • Parameters: None.

RXTRC

Tests the external trace indicator.

Note: Because the RXTRC exit is called after every Rexx instruction, enabling this exit slows Rexx procedure execution. The SetThreadTrace() method can turn on Rexx tracing without the between-instruction polling.

RXTRCTST

Tests the external trace indicator.

  • When called: When the interpreter polls for an external trace event. The exit is called after completion of every Rexx instruction.

  • Default action: None.

  • Exit action: Return the current state of external tracing (either TRUE or FALSE).

  • Continuation: When the exit handler switches from FALSE to TRUE, the Rexx interpreter enters the interactive Rexx debug mode using TRACE ?R level of tracing. When the exit handler switches from TRUE to FALSE, the Rexx interpreter exits the interactive debug mode.

  • Parameter list:

    typedef struct {
       struct {
          unsigned rxftrace : 1;        /* External trace setting        */
       } rxtrc_flags;
    } RXTRCTST_PARM;

    If the exit handler switches rxftrace to TRUE, Rexx switches on the interactive debug mode. If the exit handler switches rxftrace to FALSE, Rexx switches off the interactive debug mode.

RXINI

Initialization processing. This exit is called as the last step of Rexx program initialization.

RXINIEXT

Initialization exit.

  • When called: Before the first instruction of the Rexx procedure is interpreted.

  • Default action: None.

  • Exit action: The exit handler can perform additional initialization. For example:

  • Parameters: None.

RXTER

Termination processing.

The RXTER exit is called as the first step of Rexx program termination.

RXTEREXT

Termination exit.

  • When called: After the last instruction of the Rexx procedure has been interpreted.

  • Default action: None.

  • Exit action: The exit handler can perform additional termination activities. For example, the exit handler can use SetContextVariable() to retrieve the Rexx variable values.

  • Parameters: None.