Channel exits must be named in the channel definition. You can do this when you first define the channels, or you can add the information later using, for example, the MQSC command ALTER CHANNEL. You can also give the channel exit names in the MQCD channel data structure. The format of the exit name depends on your WebSphere MQ platform; see MQCD - Channel definition or the WebSphere MQ Script (MQSC) Command Reference book for information.
If the channel definition does not contain a user-exit program name, the user exit is not called.
The channel auto-definition exit is the property of the queue manager, not the individual channel. In order for this exit to be called, it must be named in the queue manager definition. To alter a queue manager definition, use the MQSC command ALTER QMGR.
User exits and channel-exit programs are able to make use of all MQI calls, except as noted in the sections that follow. To get the connection handle, an MQCONN must be issued, even though a warning, MQRC_ALREADY_CONNECTED, is returned because the channel itself is connected to the queue manager.
For exits on client-connection channels, the queue manager to which the exit tries to connect, depends on how the exit was linked. If the exit was linked with MQM.LIB (or QMQM/LIBMQM on iSeries) and you do not specify a queue manager name on the MQCONN call, the exit will try to connect to the default queue manager on your system. If the exit was linked with MQM.LIB (or QMQM/LIBMQM on iSeries) and you specify the name of the queue manager that was passed to the exit through the QMgrName field of MQCD, the exit tries to connect to that queue manager. If the exit was linked with MQIC.LIB or any other library, the MQCONN call will fail whether you specify a queue manager name or not.
An exit runs in the same thread as the MCA itself and uses the same connection handle. So, it runs inside the same UOW as the MCA and any calls made under syncpoint are committed or backed out by the channel at the end of the batch.
Therefore, a channel message exit could send notification messages that will only be committed to that queue when the batch containing the original message is committed. So, it is possible to issue syncpoint MQI calls from a channel message exit.
Channel-exit programs should not modify the Channel data structure (MQCD). They can actually change the BatchSize parameter and a security exit can set the MCAUserIdentifier parameter, but ChannelType and ChannelName must not be changed.
Also, for programs written in C, non-reentrant C library function should not be used in a channel-exit program.
All exits are called with a channel exit parameter structure (MQCXP), a channel definition structure (MQCD), a prepared data buffer, data length parameter, and buffer length parameter. The buffer length must not be exceeded:
LU 6.2:
TCP:
UDP:
NetBIOS:
SPX:
It is permissible for the exit to return an alternate buffer, together with the relevant parameters. See Chapter 45, Channel-exit programs for call details.
The exits are invoked as if by an z/OS LINK, in:
The link-edited modules must be placed in the data set specified by the CSQXLIB DD statement of the channel initiator address space procedure; the names of the load modules are specified as the exit names in the channel definition.
When writing channel exits for z/OS without CICS, the following rules apply:
For storage that is to persist between invocations, use the z/OS STORAGE service; there is no suitable service in C.
The exception to this rule is that security channel exits may issue commit and backout MQI calls. To do this, code the verbs CSQXCMT and CSQXBAK in place of MQCMIT/CSQBCMT and MQBACK/CSQBBAK.
In general, therefore, SVCs, PCs, and I/O should be avoided. Instead, the MQXWAIT call should be used.
For I/O and other facilities that do not provide non-blocking facilities or an ECB to wait on, a separate subtask should be ATTACHed, and its completion waited for by MQXWAIT; because of the overhead that this technique incurs, it is recommended that this be used only by the security exit.
The following exit samples are provided with WebSphere MQ for z/OS:
In WebSphere MQ for z/OS using CICS, an exit program must be written in Assembler, C, COBOL, or PL/I. In CICS, the exits are invoked with EXEC CICS LINK with the parameters passed by pointers (addresses) in the CICS communication area (COMMAREA). The exit programs, named in the channel definitions, reside in a library in the DFHRPL concatenation. They must be defined in the CICS system definition file CSD, and must be enabled.
User-exit programs can also make use of CICS API calls, but you should not issue syncpoints because the results could influence units of work declared by the MCA.
Do not update any resources controlled by a resource manager other than WebSphere MQ for z/OS, including those controlled by CICS Transaction Server for z/OS.
Any non-WebSphere MQ for z/OS resources updated by an exit are committed, or backed out, at the next syncpoint issued by the channel program. If a sender is unable to synchronize with its partner, these CICS Transaction Server for z/OS resources are backed out even though WebSphere MQ for z/OS resources are held in-doubt until the next opportunity to re-synchronize.
The exit is a program object written in the C/400(R), ILE COBOL/400(R) or ILE RPG/400(R) language. The exit program names and their libraries are named in the channel definition.
Observe the following conditions when creating and compiling an exit program:
The exit is a DLL that must be written in C. To ensure that it can be loaded when required, specify the full path name in the DEFINE CHANNEL command, or if you are using Version 5.1 or later, enter the path name in the ExitPath stanza of the QM.INI file. The value in the ExitPath stanza of the QM.INI file defaults to c:\mqm\exits. You can change this value in QM.INI or you can override it by specifying a full path name on the DEFINE CHANNEL command.
Define a dummy MQStart() routine in the exit and specify MQStart as the entry point in the shared library. Figure 127 shows how to set up entry to your program:
Figure 127. Sample source code for a channel exit on OS/2
#include <cmqc.h> #include <cmqxc.h> void MQStart() {;} /* dummy entry point - for consistency only */ void MQENTRY ChannelExit ( PMQVOID pChannelExitParms, PMQVOID pChannelDefinition, PMQLONG pDataLength, PMQLONG pAgentBufferLength, PMQVOID pAgentBuffer, PMQLONG pExitBufferLength, PMQPTR pExitBufferAddr) { ... Insert code here } |
Figure 128 shows a sample definition file that gives the entry point to the exit program.
Figure 128. Sample DEF file for a channel exit on OS/2
LIBRARY csqos2it INITINSTANCE TERMINSTANCE PROTMODE DESCRIPTION 'channel exit ' CODE SHARED LOADONCALL DATA NONSHARED MULTIPLE HEAPSIZE 4096 STACKSIZE 8192 EXPORTS csqos2it; |
Use a make file like the one shown in Figure 129 to compile and link your program to create the DLL.
Figure 129. Sample make file for a channel exit on OS/2
# MAKE FILE TO CREATE AN MQSERIES EXIT # Make File Creation run in directory: # D:\EXIT; .SUFFIXES: .SUFFIXES: .c .cpp .cxx CSQOS2IT.DLL: \ csqos2it.OBJ \ MAKEOS2 ICC.EXE @<< /Fe"CSQOS2IT.DLL" mqm.lib csqos2it.def csqos2it.OBJ << IMPLIB CSQOS2IT.LIB CSQOS2IT.DLL {.}.c.obj: ICC.EXE /Ge- /G5 /C .\$*.c {.}.cpp.obj: ICC.EXE /Ge- /G5 /C .\$*.cpp {.}.cxx.obj: ICC.EXE /Ge- /G5 /C .\$*.cxx !include MAKEOS2.DEP |
The exit is a DLL that must be written in C. It must be placed in a directory pointed to by LIBPATH to ensure it can be loaded when required. Define a dummy MQStart() routine in the exit and specify MQStart as the entry point in the shared library. Figure 130 shows how to set up an entry to your program:
Figure 130. Sample source code for a channel exit on Windows 3.1
#include <cmqc.h> #include <cmqxc.h> void MQStart() {;} /* dummy entry point - for consistency only */ void MQENTRY ChannelExit ( PMQVOID pChannelExitParms, PMQVOID pChannelDefinition, PMQLONG pDataLength, PMQLONG pAgentBufferLength, PMQVOID pAgentBuffer, PMQLONG pExitBufferLength, PMQPTR pExitBufferAddr) { ... Insert code here } |
The exit is a DLL that must be written in C.
If the exit is on a Windows client, specify the path name on the All Queue Managers page of the WebSphere MQ properties (accessed from the WebSphere MQ services snap-in).
The WebSphere MQ Services snap-in is described in the WebSphere MQ System Administration Guide manual.
The default exit path is c:\WINNT\Profiles\All Users\Application Data\MQSeries\EXITS. You can change this value or you can override it by specifying a full path name on the DEFINE CHANNEL command.
Define a dummy MQStart() routine in the exit and specify MQStart as the entry point in the library. Figure 131 shows how to set up an entry to your program:
Figure 131. Sample source code for a channel exit on Windows
#include <cmqc.h> #include <cmqxc.h> void MQStart() {;} /* dummy entry point - for consistency only */ void MQENTRY ChannelExit ( PMQCXP pChannelExitParms, PMQCD pChannelDefinition, PMQLONG pDataLength, PMQLONG pAgentBufferLength, PMQVOID pAgentBuffer, PMQLONG pExitBufferLength, PMQPTR pExitBufferAddr) { ... Insert code here } |
In order to access the fields pointed to by pChannelExitParms and pChannelDefinition you need to insert the following lines in your exit program:
·
·
·
/* Variable definitions */
·
·
·
PMQCXP pParms; PMQCD pChDef;
·
·
·
/* Code */
·
·
·
pParms = (PMQCXP)pChannelExitParms; pChDef = (PMQCD)pChannelDefinition;
The pointers pParms and pChDef can then be dereferenced to access individual fields.
When writing channel exits for these products using Visual C++, you should do the following:
Figure 132. Sample DEF file for Windows NT, Windows 95, Windows 98, or Windows
LIBRARY exit PROTMODE DESCRIPTION 'Provides Retry and Channel exits' CODE SHARED LOADONCALL DATA NONSHARED MULTIPLE HEAPSIZE 4096 STACKSIZE 8192 EXPORTS Retry |
The exit is a dynamically loaded object that must be written in C. To ensure that it can be loaded when required, specify the full path name in the DEFINE CHANNEL command or enter the path name in the ExitPath stanza of the QM.INI file. If the exit is on an AIX client, specify the path name in the ClientExitPath stanza of the MQS.INI file. The value in the ExitPath stanza of the QM.INI file or the ClientExitPath stanza of the MQS.INI file defaults to /var/mqm/exits. You can change this value or you can override it by specifying a full path name on the DEFINE CHANNEL command.
Define a dummy MQStart() routine in the exit and specify MQStart as the entry point in the module. Figure 133 shows how to set up an entry to your program:
Figure 133. Sample source code for a channel exit on AIX
#include <cmqc.h> #include <cmqxc.h> void MQStart() {;} /* dummy entry point - for consistency only */ void MQENTRY ChannelExit ( PMQVOID pChannelExitParms, PMQVOID pChannelDefinition, PMQLONG pDataLength, PMQLONG pAgentBufferLength, PMQVOID pAgentBuffer, PMQLONG pExitBufferLength, PMQPTR pExitBufferAddr) { ... Insert code here } |
Figure 134 shows the compiler and loader commands for channel-exit programs on AIX.
Figure 134. Sample compiler and loader commands for channel exits on AIX
$ cc -c exit.c $ ld -o exit exit.o -bE:exit.exp -H512 -T512 -e MQStart -bM:SRE $ cp exit /usr/xmp/lib # (or wherever you require) |
Figure 136 shows a sample make file that can be used to build a WebSphere MQ exit program, and Figure 135 shows a sample export file for this make file.
Figure 135. Sample export file for AIX
#! csqaixit MQStart |
Figure 136. Sample make file for AIX
# MAKE FILE TO BUILD A WEBSPHERE MQ EXIT ON AIX MQIDIR = /usr/mqm MQILIBDIR = $(MQIDIR)/lib MQIINCDIR = $(MQIDIR)/inc LIBEXIT = -lmqm CFLAGS = -g -bloadmap:muck ALL : CSQAIXIT csqaixit: csqaixit.o xlc -L $(MQILIBDIR) $(LIBEXIT) csqaixit.o -o csqaixit \ -bE:csqaixit.exp -H512 -T512 -e MQStart -bM:SRE csqaixit.o : csqaixit.c xlc -c csqaixit.c \ -I $(MQIINCDIR) |
The user exit is a dynamically loaded image that can be shared, with its name taken from the format of the message. It must be written in C. The object's name must be in uppercase, for example MYFORMAT. The shareable image must be placed in sys$share or a location defined by a logical name at executive level for it to be loaded.
User exits must be installed as known images. Figure 137 shows how to set up an entry to your program:
Figure 137. Sample source code for a channel exit on Compaq OpenVMS Alpha
#include <cmqc.h> #include <cmqxc.h> void MQStart() {;} /* dummy entry point */ void MQENTRY ChannelExit ( PMQVOID pChannelExitParms, PMQVOID pChannelDefinition, PMQLONG pDataLength, PMQLONG pAgentBufferLength, PMQVOID pAgentBuffer, PMQLONG pExitBufferLength, PMQPTR pExitBufferAddr) { ... Insert code here } |
In the example, MQSTART is the initialization routine entry point for the MYFORMAT shareable image. The names of the routines that are called by the exit must be made universal.
$ CC /INCLUDE_DIRECTORY=MQS_INCLUDE exitname.C $ LINK /SHARE=SYS$SHARE:[SYSLIB]MYFORMAT exitname.OBJ,MYFORMAT/OPTIONS
The contents of MYFORMAT.OPT vary depending on what platform you are working on:
On AXP:
SYS$SHARE:MQM/SHAREABLE SYMBOL_VECTOR=(MQSTART=PROCEDURE)
On VAX:
SYS$SHARE:MQM/SHAREABLE UNIVERSAL=MQSTART
If you are using threaded applications linked with the pthread library, you must also build a second copy of the exit with the thread options and libraries:
$ CC /INCLUDE_DIRECTORY=MQS_INCLUDE exitname.C $ LINK /SHARE=SYS$SHARE:MYFORMAT exitname.OBJ,MYFORMAT/OPTIONS
Again, the contents of MYFORMAT.OPT vary depending on what platform you are working on:
On AXP:
SYS$SHARE:MQM_R/SHAREABLE SYS$SHARE:CMA$OPEN_RTL.EXE/SHAREABLE SYMBOL_VECTOR'-(MQSTART=PROCEDURE)
On VAX:
SYS$SHARE:MQM_R/SHAREABLE SYS$SHARE:CMA$OPEN_RTL.EXE/SHAREABLE UNIVERSAL=MQSTART
The exit is a dynamically loaded object that must be written in C. To ensure that it can be loaded when required, link and copy the exit to the /usr/lib directory. Define a dummy MQStart() routine in the exit and specify MQStart as the entry point in the module. Figure 138 shows how to set up an entry to your program:
Figure 138. Sample source code for a channel exit on Compaq Tru64 UNIX
#include <cmqc.h> #include <cmqxc.h> void MQStart() {;} /* dummy entry point - for consistency only */ void MQENTRY ChannelExit ( PMQVOID pChannelExitParms, PMQVOID pChannelDefinition, PMQLONG pDataLength, PMQLONG pAgentBufferLength, PMQVOID pAgentBuffer, PMQLONG pExitBufferLength, PMQPTR pExitBufferAddr) { ... Insert code here } |
Figure 139 shows the compiler and loader commands for channel-exit programs on Compaq Tru64 UNIX.
Figure 139. Sample compiler and loader commands for channel exits on Compaq Tru64 UNIX
$ cc -stdl -c -I/opt/mqm/inc exit.c $ ld -o exit exit.o -shared -L/opt/mqm/lib -lmqm -e MQStart -lc $ cp exit /usr/lib |
The exit is a dynamically loaded object that must be written in C. To ensure that it can be loaded when required, specify the full path name in the DEFINE CHANNEL command or enter the path name in the ExitPath stanza of the QM.INI file. If the exit is on an HP-UX client, specify the path name in the ClientExitPath stanza of the MQS.INI file. The value in the ExitPath stanza of the QM.INI file or the ClientExitPath stanza of the MQS.INI file defaults to /var/mqm/exits. You can change this value or you can override it by specifying a full path name on the DEFINE CHANNEL command.
Define a dummy MQStart() routine in the exit and specify MQStart as the entry point in the module. Figure 140 shows how to set up an entry to your program:
Figure 140. Sample source code for a channel exit on HP-UX
#include <cmqc.h> #include <cmqxc.h> void MQStart() {;} /* dummy entry point - for consistency only */ void MQENTRY ChannelExit ( PMQVOID pChannelExitParms, PMQVOID pChannelDefinition, PMQLONG pDataLength, PMQLONG pAgentBufferLength, PMQVOID pAgentBuffer, PMQLONG pExitBufferLength, PMQPTR pExitBufferAddr) { ... Insert code here } |
Figure 141 shows the compiler and loader commands for channel-exit programs on HP-UX.
Figure 141. Sample compiler and loader commands for channel exits on HP-UX
$ cc -c +z exit.c $ ld -o exit exit.o +b : -c exit.exp +I MQStart -b $ cp exit /usr/xmp/lib # (or wherever you require) |
The exit is a dynamically loaded object that must be written in C. Specify the full path name in the DEFINE CHANNEL command. Define a dummy MQStart() routine in the exit and specify MQStart as the entry point in the module. Figure 142 shows how to set up an entry to your program:
Figure 142. Sample source code for a channel exit on AT&T GIS UNIX
#include <cmqc.h> #include <cmqxc.h> void MQStart() {;} /* dummy entry point */ void MQENTRY ChannelExit ( PMQVOID pChannelExitParms, PMQVOID pChannelDefinition, PMQLONG pDataLength, PMQLONG pAgentBufferLength, PMQVOID pAgentBuffer, PMQLONG pExitBufferLength, PMQPTR pExitBufferAddr) { ... Insert code here } |
Figure 143 shows the compiler and loader commands for channel-exit programs on AT&T GIS UNIX12.
Figure 143. Sample compiler and loader commands for channel exits on AT&T GIS UNIX
$ cc -c PIC exit.c $ ld -o exit -G exit.o $ cp exit /usr/xmp/lib # (or wherever you require) |
The exit is a dynamically loaded object that must be written in C. To ensure that it can be loaded when required, specify the full path name in the DEFINE CHANNEL command or enter the path name in the ExitPath stanza of the QM.INI file. If the exit is on a Solaris client, specify the path name in the ClientExitPath stanza of the MQS.INI file. The value in the ExitPath stanza of the QM.INI file or the ClientExitPath stanza of the MQS.INI file defaults to /var/mqm/exits. You can change this value or you can override it by specifying a full path name on the DEFINE CHANNEL command.
Define a dummy MQStart() routine in the exit and specify MQStart as the entry point in the module. Figure 144 shows how to set up an entry to your program:
Figure 144. Sample source code for a channel exit on Solaris
#include <cmqc.h> #include <cmqxc.h> void MQStart() {;} /* dummy entry point */ void MQENTRY ChannelExit ( PMQVOID pChannelExitParms, PMQVOID pChannelDefinition, PMQLONG pDataLength, PMQLONG pAgentBufferLength, PMQVOID pAgentBuffer, PMQLONG pExitBufferLength, PMQPTR pExitBufferAddr) { ... Insert code here } |
Figure 145 shows the compiler and loader commands for channel-exit programs on Solaris.
Figure 145. Sample compiler and loader commands for channel exits on Solaris
$ cc -c -KPIC exit.c $ ld -G exit.o -o exit $ cp exit /usr/xmp/lib # (or wherever you require) |
The exit is a dynamically loaded object that must be written in C. Specify the full path name in the DEFINE CHANNEL command. Define a dummy MQStart() routine in the exit and specify MQStart as the entry point in the module. Figure 146 shows how to set up an entry to your program:
Figure 146. Sample source code for a channel exit on SINIX and DC/OSx
#include <cmqc.h> #include <cmqxc.h> void MQStart() {;} /* dummy entry point */ void MQENTRY ChannelExit ( PMQVOID pChannelExitParms, PMQVOID pChannelDefinition, PMQLONG pDataLength, PMQLONG pAgentBufferLength, PMQVOID pAgentBuffer, PMQLONG pExitBufferLength, PMQPTR pExitBufferAddr) { ... Insert code here } |
Figure 147 shows the compiler and loader commands for channel-exit programs on SINIX and DC/OSx.
Figure 147. Sample compiler and loader commands for channel exits on SINIX and DC/OSx
$ cc -Kpic exit.c -G -o exit -lmqm -lmqmcs $ cp exit /opt/mqm/lib # (or wherever you require) |
For DC/OSx, version cd087 and later, append the following to the cc line:
-liconv -lresolv
For earlier versions of DC/OSx, append the following to the cc line:
-liconv
MQSeries for Compaq NonStop Kernel supports a single, statically bound channel-exit program, whose entry point is MQ_CHANNEL_EXIT(). The exit must be written in C. MQSeries for Compaq NonStop Kernel provides a stub function for this exit that acts as a placeholder for user-supplied exit code. In the supplied stub function, the ExitResponse field in MQCXP (channel exit parameter structure) is set to MQXCC_CLOSE_CHANNEL, which causes the MCA to close the channel. No other fields in MQCXP are modified.
You replace the supplied stub function in the MCA executable images with your own user exit code using the Tandem BIND utility BEXITE. Only the Tandem Common Runtime Environment (CRE) interface for the WIDE memory model is supported.
In MQSeries for Compaq NonStop Kernel, there is a single entry point for all channel exits. In other MQSeries Version 5 products, there are entry points specific to each channel type and function. It is possible to use channel-exit programs written for other MQSeries Version 5 products by calling those programs from MQ_CHANNEL_EXIT(). To determine the type of exit being called, examine the ExitId field of MQCXP, then extract the associated exit-program name from the MsgExit, MsgRetryExit, ReceiveExit, SendExit, or SecurityExit field of MQCD.
The channel attributes that define the names of user exits are:
If these channel attributes are left blank, the channel user exit is not invoked. If any of the channel attributes is nonblank, the MQ_CHANNEL_EXIT() user exit program is invoked for the corresponding function. Note that the text-string value of the channel attribute is not used to determine the name of the user exit program, since only a single entry point, MQ_CHANNEL_EXIT(), is supported in MQSeries for Compaq NonStop Kernel. However, the values of these channel attributes are passed to MQ_CHANNEL_EXIT() in the MQCD (channel data) structure. The function of the channel exit (that is, whether the exit corresponds to a Message, Message-retry, Receive, Security or Send Exit) is passed to MQ_CHANNEL_EXIT() in the ExitId field of the MQCXP (Channel Exit Parameters) structure.
MQSeries for Compaq NonStop Kernel does not support the following channel attributes:
Dynamically bound libraries are not supported by WebSphere MQ for Compaq NonStop Kernel. Channel exits (and data-conversion exits) are implemented by including statically bound stub functions in the WebSphere MQ libraries and executables which can be replaced using the REPLACE bind option.
A channel exit function must be written in C, must be called CHANNELEXIT (see sample MQSVCHX), and can be bound into the chosen executable (or library) using the TACL macro BEXITE.
The function CHANNELEXIT must handle each of the possible exit calls (security, message-retry, message, send, and receive). You may write your own functions to do this.
Use the TACL macro BCHXALL to bind the data conversion exit into all required WebSphere MQ processes. For example:
BCHXALL source-exit-file-or-library
/********************************************************************/ /* */ /* Program name: MQSVCHXE */ /* */ /* Description: Sample C skeleton of a Channel Exit controlling */ /* function */ /* */ /* Statement: Licensed Materials - Property of IBM */ /* */ /* 33H2205, 5622-908 */ /* 33H2267, 5765-623 */ /* 29H0990, 5697-176 */ /* (C) Copyright IBM Corp. 1994, 1995 */ /* */ /********************************************************************/ /* */ /* Function: */ /* */ /* MQSVCHXE is a sample C skeleton of a Channel Exit controlling */ /* function */ /* */ /* The function controls the calls to user-defined channel exits */ /* */ /* */ /* Once complete the code should be compiled into a loadable */ /* object, the name of the object should be the name of the */ /* format to be converted. Instructions on how to do this are */ /* contained in the README file in the current directory. */ /* */ /********************************************************************/ /* */ /* MQSVFCXE takes the parameters defined for a Data Conversion */ /* exit routine in the CMQXC.H header file. */ /* */ /********************************************************************/ #include <cmqc.h> /* For MQI datatypes */ #include <cmqxc.h> /* For MQI exit-related definitions */ #include <amqsvmht.h> /* For sample macro definitions */ /********************************************************************/ /* Insert the function prototypes for the functions produced by */ /* the data conversion utility program. */ /********************************************************************/ MQDATACONVEXIT CHANNELEXIT; /********************************************************************/ /* On some Unix systems, the name of this function is not important */ /* as it is not actually used to call the conversion exit but it */ /* must be an exported symbol or the entry point to the module. On */ /* the TANDEM NSK this function MUST be called CHANNELEXIT */ /********************************************************************/ void MQENTRY CHANNELEXIT( PMQVOID pChannelExitParms, /* Channel exit parameter block */ PMQVOID pChannelDefinition, /* Channel definition */ PMQLONG pDataLength, /* Length of data */ PMQLONG pAgentBufferLength, /* Length of agent buffer */ PMQVOID pAgentBuffer, /* Agent buffer */ PMQLONG pExitBufferLength, /* Length of exit buffer */ PMQPTR pExitBufferAddr) /* Address of exit buffer */ { PMQCXP pCEP = pChannelExitParms; PMQCD pCD = pChannelDefinition; MQLONG ExitId = pCEP->ExitId; MQLONG ExitReason = pCEP->ExitReason; pCEP->ExitResponse = MQXCC_OK ; /* Call the handling function according to the ExitId */ /* By default, there are no exits. If there are, then */ /* this function will have been replaced by a bind */ switch (ExitId) { case MQXT_CHANNEL_SEC_EXIT: if (strlen(pCD->SecurityExit) == 0) { pCEP->ExitResponse = MQXCC_SUPPRESS_FUNCTION ; } else { /* Call the security exit function here */ } break; case MQXT_CHANNEL_MSG_EXIT: /* Call the channel message exit function here */ if (strlen(pCD->MsgExit) == 0) { pCEP->ExitResponse = MQXCC_SUPPRESS_FUNCTION ; } else { /* Call the message exit function here */ } break; case MQXT_CHANNEL_SEND_EXIT: /* Call the channel send exit function here */ if (strlen(pCD->SendExit) == 0) { pCEP->ExitResponse = MQXCC_SUPPRESS_FUNCTION ; } else { /* Call the send exit function here */ } break; case MQXT_CHANNEL_RCV_EXIT: /* Call the channel receive exit function here */ if (strlen(pCD->ReceiveExit) == 0) { pCEP->ExitResponse = MQXCC_SUPPRESS_FUNCTION ; } else { /* Call the receive exit function here */ } break; case MQXT_CHANNEL_MSG_RETRY_EXIT: /* Call the channel retry exit function here */ if (strlen(pCD->MsgRetryExit) == 0) { pCEP->ExitResponse = MQXCC_SUPPRESS_FUNCTION ; } else { /* Call the message retry exit function here */ } break; default: /* if the exit isn't recognized, stop it from being called again */ pCEP->ExitResponse = MQXCC_SUPPRESS_EXIT ; break; } return; } /********************************************************************/ /* */ /* END OF MQSVCHXE */ /* */ /********************************************************************/