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:
The administration of resources at the beginning and the end of interpretation
Linkages to external functions and subcommand handlers
Special language features; for example, input and output to standard resources
Polling for halt and external trace events
Direct exit handlers are specified when the interpreter instance is created, and reside as entry points within the application that creates the interpreter instance.
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:
is the RexxExitContext vector that provides access to interpreter services for this exit handler.
is the major function code defining the type of exit call.
is the subfunction code defining the exit event for the call.
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 handlers return an integer value that signals one of the following actions:
The exit handler processed the exit subfunction and updated the subfunction parameter list as required. The Rexx interpreter continues with processing as usual.
The exit handler did not process the exit subfunction. The Rexx interpreter processes the subfunction as if the exit handler were not called.
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".
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.
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.
The Rexx interpreter supports the following system exits:
External function call exit.
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.
Object oriented external function call exit.
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.
Scripting external function call exit.
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.
Subcommand call exit.
Call a subcommand handler.
External data queue exit.
Pull a line from the external data queue.
Place a line in the external data queue.
Return the number of lines in the external data queue.
Set the active external data queue name.
Standard input and output exit.
Write a line to the standard output stream for the SAY instruction.
Write a line to the standard error stream for the Rexx trace or Rexx error messages.
Read a line from the standard input stream for PULL or PARSE PULL.
Read a line from the standard input stream for interactive debugging.
NOVALUE exit.
Process a variable NOVALUE condition.
VALUE built-in function extension.
Process a VALUE() built-in function call for an unknown named environment.
Halt processing exit.
Test for a HALT condition.
Clear a HALT condition.
External trace exit.
Test for an external trace event.
Initialization exit.
Allow additional Rexx procedure initialization.
Termination exit.
Process Rexx procedure termination.
The following sections describe each exit subfunction, including:
The service the subfunction provides
When Rexx calls the exit handler
The default action when the exit is not provided or the exit handler does not process the subfunction
The exit action
The subfunction parameter list
Processes calls to external functions.
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.
Processes calls to external functions.
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.
Processes calls to external functions.
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.
Processes calls to subcommand handlers.
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.
External data queue exit.
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.
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).
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.
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.
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.
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.
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.
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.
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.
Processes NOVALUE variable conditions.
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;
Extends the environments available to the VALUE() built-in function.
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.
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.
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.
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.
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.
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.
Initialization processing. This exit is called as the last step of Rexx program initialization.
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:
Use SetContextVariable() API to initialize application-specific variables.
Use SetThreadTrace() API to switch on the interactive Rexx debug mode.
Parameters: None.
Termination processing.
The RXTER exit is called as the first step of Rexx program termination.
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.