A global user exit program must be written in assembler language and must be quasireentrant. However, if your user exit program calls the XPI, it must be fully reentrant. 2 (For details about coding programs using XPI calls, refer to The user exit programming interface (XPI).)
The following register values are provided on entry to an exit program:
Write-to-operator (WTO) commands use register 1. If your exit program uses WTO commands, you should save the address of DFHUEPAR first.
If you want to issue operating system requests that use register 13 to point to a save area, you must switch register 13 to point to another save area. You must restore register 13 to its original contents before returning from your user exit program to the caller.
No other register values are guaranteed, and they should not be relied on. The exit program should save and restore any registers that it modifies, using the save area addressed by register 13.
The rules governing the use of CICS services in exit programs vary, depending on the exit point from which the exit program is being invoked. The following general rules apply:
An exit program invoked at an exit that does not support the use of EXEC CICS commands should not call a task-related user exit program (TRUE). (Calling a TRUE is equivalent to issuing an EXEC CICS command.) Exceptions to this rule are programs invoked from the XFCFRIN and XFCFROUT exits, which may call a TRUE. TRUEs are described in Task-related user exit programs.
For example, if one invocation of an exit program issues an EXEC CICS STARTBR command, and the next invocation of the exit program for that same task issues an EXEC CICS READNEXT command, the READNEXT fails with an INVREQ condition.
All exit programs that issue EXEC CICS commands, and that use the DFHEIENT macro, should use the DFHEIRET macro to set a return code and return to CICS. See Returning values to CICS.
There are a number of exits where you can use both EXEC CICS commands and XPI calls, but you should ensure that there is no conflict in the usage of register 13. To avoid such conflict, use the DATAREG option on the DFHEIENT macro (see XPI register usage for information).
For an example of how to use EXEC CICS commands and XPI calls in the same global user exit program, see Appendix F. The example program for the XTSEREQ global user exit, DFH$XTSE
Global user exit programs cannot access channels and containers created by application programs. They can, however, create their own channels and pass them to programs which they call.
For information about channels and containers, see the CICS Application Programming Guide.
Assembler programs translated with the LEASM option cannot be used as global user exit programs.
LEASM is used to produce Language Environment® conforming main programs in assembler. For information about the LEASM translator option, see the CICS Application Programming Guide.
If you use the Execution Diagnostic Facility (EDF) to debug your applications, you must take care when compiling exit programs that issue EXEC CICS commands.
Normally, if an exit program issues EXEC CICS commands, these are displayed by EDF, if the latter is active. They appear between the "Start of Command" and "End of Command" screens for the command that caused the exit to be driven. If you want to suppress the display of EXEC CICS commands issued by your exit program, you must specify the NOEDF option when you translate the program. You should always specify NOEDF for programs in a production environment.
If an exit program that may be invoked during recovery processing issues EXEC CICS commands, you must translate it with the NOEDF option. Failure to do so may cause EDF to abend.
When you enable an exit program, you can ask CICS to provide a global work area for the exit program. An exit program can have its own global work area, or it can share a work area that is owned by another exit program. Note that the work area is associated with the exit program rather than with the exit point. For ease of problem determination, the global work area should be shared only by exit programs that are invoked from the same management module or domain. The address and length of the global work area are addressed by parameters UEPGAA and UEPGAL of the DFHUEPAR parameter list, which is described in DFHUEPAR standard parameters. If a user exit program does not own a global work area, UEPGAA is set to zero.
Application programs can communicate with user exit programs that use or share the same global work area. The application program uses the EXEC CICS EXTRACT EXIT command to obtain the address and length of the global work area.
A work area is freed only when all of the exit programs that use it are disabled. For examples of how to use a global work area, see the sample global user exit programs. They are listed in Sample global user exit programs.
If tracing is active, an entry in the CICS trace table can be made immediately before and immediately after the execution of an exit program. To specify that these entries are to be made, use the UE option of either:
For global user exits in domains, extra trace calls giving more information are also available if you have set the AP option of EXEC CICS SET TRACETYPE to level 1 or 2. For information about trace entries, refer to the CICS Problem Determination Guide.
In some cases, when tracing is active, you can also make trace entries from within a user exit program, using the XPI DFHTRPTX TRACE_PUT macro described in The user exit programming interface (XPI). The individual descriptions of the global user exit points show whether the XPI DFHTRPTX macro can be used at each point.
The address of a parameter list is passed to the user exit program in register 1. The list contains some standard parameters that are passed to all global user exit programs, and may also contain some exit-specific parameters that are unique to the exit point from which the exit program is being invoked. Not all of the exit points have these extra parameters.
The exit-specific parameters are described with the individual exits in the section List of global user exit points. The standard parameter list is described in the following section.
You can map the parameter list using the DSECT DFHUEPAR, which is generated by the macro instruction
DFHUEXIT TYPE=EP,ID=exit_point_identifier
The ID parameter provides the extra data definitions that you need to map any exit-specific parameters. For example, the macro instruction
DFHUEXIT TYPE=EP,ID=XTDIN
generates the DSECT to map the standard parameters followed by the parameters that are specific to exit point XTDIN in the transient data program. If your exit program is to be invoked at more than one exit point, you can code up to 256 characters of relevant exit identifiers on a single DFHUEXIT macro instruction. For example:
DFHUEXIT TYPE=EP,ID=(XMNOUT,XSTOUT,XTDIN)
If your exit program is to be invoked at every global user exit point, you can code:
DFHUEXIT TYPE=EP,ID=ALL
If your user exit program is to be used both as a global user exit program and as a task-related user exit program, you must code both:
DFHUEXIT TYPE=EP,ID=exit_point_identifier
and:
DFHUEXIT TYPE=RM
(in this order) to generate the DSECTs appropriate to both types of user exit.
If a global user exit program needs to use the DFHRMCAL macro to invoke an external RMI, the DFHRMCAL macro instruction must follow the DFHUEXIT macro.
DFHUEPAR DSECT
* STANDARD PARAMETERS
UEPEXN DS A ADDRESS OF EXIT NUMBER
UEPGAA DS A ADDRESS OF GLOBAL WORK AREA
* (ZERO = NO WORK AREA)
UEPGAL DS A ADDRESS OF GLOBAL WORK AREA LENGTH
UEPCRCA DS A ADDRESS OF CURRENT RETURN-CODE
UEPTCA DS A RESERVED
UEPCSA DS A RESERVED
UEPEPSA DS A ADDRESS OF REGISTER SAVE AREA
* FOR USE BY EXIT PROGRAM
UEPHMSA DS A ADDRESS OF SAVE AREA USED FOR
* HOST MODULE'S REGISTERS
UEPGIND DS A ADDRESS OF CALLER'S TASK INDICATORS
UEPSTACK DS A ADDRESS OF KERNEL STACK ENTRY
UEPXSTOR DS A ADDRESS OF STORAGE FOR XPI PARAMETERS
UEPTRACE DS A ADDRESS OF TRACE FLAG
DFHUEXIT TYPE=EP generates a list of equated values that relate the exit names (exitids) to the exit numbers used internally by CICS to identify the exits. You should always use the exitids, because the exit numbers may change in any future releases of CICS.
For an example of
how an exit program can set a different return code from that returned
by a previous exit program at the same exit point, see the code snippet
in Invoking more than one exit program at a single exit.
Apart from register 15, which contains the return code value from the exit program, the values in this save area are used by CICS to reload the registers when returning to the calling CICS module. They should not be corrupted.
This address is not passed to global user exit programs invoked from exit points in CICS domains.
The first indicator byte can take one of two symbolic values, UEPGANY and UEPGCICS, which you can test to determine whether data locations can be above or below 16MB, and whether the application’s storage is in CICS-key or user-key storage:
The second and third bytes contain a value indicating the TCB mode of the global user exit program's caller. This is represented in DFHUEPAR as both a two-character code and a symbolic value, as follows:
Symbolic value | 2-byte code | Description |
---|---|---|
UEPTQR | QR | The quasi-reentrant mode TCB |
UEPTRO | RO | The resource-owning mode TCB |
UEPTCO | CO | The concurrent mode TCB |
UEPTSZ | SZ | The FEPI mode TCB |
UEPTRP | RP | The ONC/RPC mode TCB |
UEPTFO | FO | The file-owning mode TCB |
UEPTSL | SL | The sockets listener mode TCB |
UEPTSO | SO | The sockets mode TCB |
UEPTS8 | S8 | The secure sockets layer mode TCB |
UEPTD2 | D2 | The CICS-DB2 housekeeping mode TCB |
UEPTJ8 | J8 | The J8 open TCB, used for JVMs that are in CICS key |
UEPTJ9 | J9 | The J9 open TCB, used for JVMs that are in user key |
UEPTJM | JM | The JM open TCB, used for the master JVM that initializes the shared class cache |
UEPTL8 | L8 | ![]() ![]() |
![]() ![]() |
![]() ![]() |
![]() ![]() |
![]() ![]() |
![]() ![]() |
![]() ![]() |
![]() ![]() |
![]() ![]() |
![]() ![]() |
At some exit points, you can influence what CICS does on return from an exit program by supplying a return code value. The return code value must be set in register 15 before leaving the exit program. Character strings equating to valid return code values are provided with the parameter list appropriate for each exit point. Always use the equated values rather than using hard-coded values. For example, at exit XMNOUT in the monitor domain, you are presented with the address of a monitoring record. If you decide in your exit program that this record should not be written to SMF, you can set the return code value UERCBYP (meaning "bypass this record") before returning to CICS, and CICS suppresses the record.
You cannot influence CICS actions in this way at all exit points. If you supply a return code value that is not expected at a particular exit point, the default return code indicating a normal response (usually UERCNORM) is assumed, unless the return code UERCPURG is set (see note below about UERCPURG). You are strongly advised not to let the return code default to the normal response as the result can be unpredictable. The normal response tells CICS to continue processing as if the exit program had not been invoked, and it is a valid option at most global user exit points. The exceptions are shown in the list of return codes provided with each exit description.
The return code currently established for an exit is addressed by parameter UEPCRCA of DFHUEPAR, and it is needed when two or more exit programs are used at one exit. For more information, see Invoking more than one exit program at a single exit.
The return codes that are valid at each of the global user exit points are described in List of global user exit points.
The CICS Data Areas manual contains definitions of the control block fields that form part of the Product-sensitive and General-use programming interfaces of CICS. Fields that are not defined in the CICS Data Areas manual as either Product-sensitive programming interface or General-use programming interface fields are not intended for your use as part of a CICS programming interface.
When you are running CICS with the storage protection facility, there are two points you need to consider for global user exits:
When you are running with storage protection active, CICS always invokes global user exit programs in CICS key. Even if you specify EXECKEY(USER) on the program resource definition, CICS forces CICS key when it passes control to the exit program. However, if a global user exit program itself passes control to another program (via a link or transfer-control command), the program thus invoked is executed according to the execution key (EXECKEY) defined in its program resource definition.
You are strongly recommended to specify EXECKEY(CICS) when defining both global user exit programs and programs to which an exit program passes control.
The storage key of storage used by global user exit programs depends on how the storage is obtained:
The default storage key for storage obtained by EXEC CICS commands is set by the TASKDATAKEY of the transaction under which the exit program is invoked.
As an example, consider a transaction defined with TASKDATAKEY(USER) that issues a file control request, which causes an XFCREQ global user exit program to be invoked. In this case, any implicit or explicit storage acquired by the exit program by means of an EXEC CICS command is, by default, in user-key storage. However, on an EXEC CICS GETMAIN command, the exit program can override the TASKDATAKEY option by specifying either CICSDATAKEY or USERDATAKEY.
If you are running CICS with the transaction isolation facility (TRANISO=YES), the exit program will inherit the subspace of the application that caused the exit to be called.
Because global user exit programs are an extension to CICS code, they are subject to the environment that CICS is running in when they are called. If an error is detected at an exit point, CICS issues messages indicating which exit program was in error, the place in the program at which the error occurred, and the name of the associated exit point. The detection of an error is not guaranteed, because it depends on the CICS environment at the time of error, and on the nature of the error. For example, CICS might not recognize a looping user exit program, since the detection mechanism may have been turned off. Also, an abend in one of the exits XPCABND, XPCTA, or XSRAB may cause CICS to terminate abnormally, because an abend during abend processing causes CICS to terminate.
Exit programs invoked at some exit points (for example, XTSEREQ, XTSEREQC, XICEREQ, XICEREQC, XTDEREQ, or XTDEREQC) can enter a loop by issuing a recursive command (such as a TS command at exit point XTSEREQ). The exits most likely to be affected provide a recursion count parameter, UEPRECUR, that you can use to prevent such loops.
When coding user exit programs, you should bear in mind that the code is executed as an extension of CICS code, rather than as a transaction, and any errors could have disastrous results.
When you have written an exit program, you must define it to CICS using the CEDA DEFINE PROGRAM command. (Note that you must specify RELOAD(NO).)
Having defined the exit program, you must also enable it. You do this using the EXEC CICS ENABLE command.3 When you have finished using the exit program, you should disable it, using the EXEC CICS DISABLE command.
For programming information about the EXEC CICS ENABLE and DISABLE commands, see the CICS System Programming Reference manual. For examples of how to enable and disable global user exit programs, see the sample programs listed in topic Sample global user exit programs.
There may be times when you want to invoke more than one exit program from a single global user exit point. For example, you might have two or more application packages that supply programs for the same CICS exit. Although such programs may work independently, you should note the following points:
The following rules apply to return codes if a second user exit program sets a different return code value from that selected by the previous program:
The following code
snippet shows how a new exit program can set a different return code
from the "current return code" returned by a previous exit
program, and cause CICS to act on the new code.
LA R15,UERCTDOK Set the contents of reg 15 to a value of 4
L R6,UEPCRCA Set reg 6 to the address of the half word
* containing the current return code
STH R15,0(,6) Store the new return code at the location
* of the current return code.
. . .
To invoke a single exit program from more than one exit point, you must issue an ENABLE command for each of the exit points. For programming information about how to issue an ENABLE command, see the CICS System Programming Reference manual. Be careful to specify GALENGTH or GAENTRYNAME on only the first ENABLE command, otherwise ‘INVEXITREQ’ may be returned.
Take into account the restrictions that apply to the use of CICS services, because these are dictated by the exit point itself rather than by the exit program. A command that can be issued from one exit point may cause problems when issued from a different exit point.
The global work area is associated with the exit program, rather than with the exit point: this means that the same global work area is used at each of the exit points at which the exit program is invoked.
All user programs defined by a program resource definition have a concurrency attribute, which can be either QUASIRENT or THREADSAFE (see the CICS Resource Definition Guide for details). By default, global user programs are defined as quasi-reentrant, which means they are given control on the CICS QR TCB (see the CICS Application Programming Guide). If the task under which the global user exit is invoked is executing on an open TCB, and the exit program is defined as quasi-reentrant, CICS switches back to the QR TCB for the execution of the exit program.
To avoid unnecesary TCB switching, you are strongly recommended to make sure that your global user programs conform to threadsafe programming standards. When you are satisfied that your exit programs are threadsafe, ensure that they are defined as CONCURRENCY(THREADSAFE). This is particularly important for exits that are invoked by tasks that are using the CICS DB2® interface and running under an L8 TCB.
If a CICS DB2 application program has been written and defined as threadsafe to obtain the benefits of the CICS open transaction environment (OTE), the benefit is lost if TCB switching is caused by a non-threadsafe exit program. You should pay particular attention to exit programs used on the mainline CICS-DB2 path: exit programs written for the XRMIIN and XRMIOUT exit points need to be made threadsafe, as well as those invoked frequently, such as XEIIN and XEIOUT, which are invoked for every CICS API request.
For more information, see in the CICS Application Programming Guide.
CICS provides two sets of sample and example global user exit programs:
The source of all the sample programs, and any associated copy books, is supplied in the CICSTS31.CICS.SDFHSAMP library. You can use the supplied programs as models on which to base your own versions.
This set of sample programs shows you how to:
The GWA sample programs and copy books are:
CICS also provides copy book DFH$PCGA for use in this sample program.
CICS also provides copy book DFH$ZCGA for use in this sample program.
DFH$PCPL is a dummy program, invoked by DFH$PCPI, that causes the XPCFTCH user exit to be driven.
DFH$PCPI consists of three main sections:
Most of the above information is obtained using EXEC CICS API commands such as:
The section performs the following processing:
The following are examples of the RDO definitions required to define the sample programs to the CSD:
DEFINE PROGRAM(DFH$PCEX) GROUP(EXITGRP)
LANGUAGE(ASSEMBLER) RELOAD(NO) RESIDENT(NO) USAGE(NORMAL)
USELPACOPY(NO) STATUS(ENABLED) CEDF(YES) DATALOCATION(ANY)
EXECKEY(CICS)
DEFINE PROGRAM(DFH$PCPI) GROUP(EXITGRP)
LANGUAGE(ASSEMBLER) RELOAD(NO) RESIDENT(NO) USAGE(NORMAL)
USELPACOPY(NO) STATUS(ENABLED) CEDF(YES) DATALOCATION(ANY)
EXECKEY(CICS)
DEFINE PROGRAM(DFH$PCPL) GROUP(EXITGRP)
LANGUAGE(ASSEMBLER) RELOAD(NO) RESIDENT(NO) USAGE(NORMAL)
USELPACOPY(NO) STATUS(ENABLED) CEDF(YES) DATALOCATION(ANY)
EXECKEY(CICS)
DEFINE PROGRAM(DFH$ZCAT) GROUP(EXITGRP)
LANGUAGE(ASSEMBLER) RELOAD(NO) RESIDENT(NO) USAGE(NORMAL)
USELPACOPY(NO) STATUS(ENABLED) CEDF(YES) DATALOCATION(ANY)
EXECKEY(CICS)
DFH$PCPI is designed to be run as a PLT program. If you write a similar program, you should define it in the second part of the PLTPI list (after the PROGRAM=DFHDELIM entry). Information about how to do this is in the CICS Resource Definition Guide.
As well as the sample programs supplied in source code, there is an example listing, DFH$XTSE, that shows you how to:
DFH$XTSE is listed in topic Appendix F. The example program for the XTSEREQ global user exit, DFH$XTSE.
CICS supplies a sample global user exit program for the Basic Mapping support exits:
CICS supplies one sample global user exit program for each of the data tables exit points. These are:
DFH$DTAD, DFH$DTLC, and DFH$DTRD are listed in the CICS Shared Data Tables Guide.
There is one dump domain sample global user exit program:
There is one sample global user exit program for the enqueue EXEC interface.
There is one sample global user exit program for the file control state program.
CICS provides three sample file control global user exit programs:
You can define these programs by including the supplied resource group, DFH$FCB, in your startup grouplist, or by using CEDA to install DFH$FCB.
You can use the XISCONA sample global user exit program to control the queueing of function-shipping and DPL requests:
This sample program implements the same basic function provided by the QUEUELIMIT and MAXQTIME parameters on a connection resource definition. These parameters are passed to the XZIQUE global user program, which can change the way in which these parameters are used:
See Sample exit program design for more details.
There is one sample global user exit program for the XLGSTRM exit point:
These sample programs show you how to write a program to be invoked at the XMEOUT exit, to do a specific task. For example, the DFH$SXP4 sample program shows you how to use the XMEOUT exit to reroute a console message to a transient data queue.
You can use this sample global user exit program to handle terminal-not-known conditions arising from START and ATI requests:
There is one sample global user exit program for the XPCTA exit point:
These sample programs are for use at the Web domain exit, XWBOPEN. The XWBOPEN exit is invoked during processing of EXEC CICS WEB OPEN and EXEC CICS INVOKE WEBSERVICE commands. It is used in making HTTP client requests from CICS as an HTTP client, which is a facility provided by CICS Web support.
The sample programs show you how to set up proxy server information or a security policy in a global work area. For example, if all the requests from your CICS system should use a single proxy server, you can specify the proxy server name as an initialization parameter. If you use a number of proxy servers or want to apply a security policy to different host names, you could load or build a table that matches host names to appropriate proxy servers or marks them as barred, which could then be used as a look-up table during processing of the EXEC CICS WEB OPEN command.