Writing and compiling channel-exit programs

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.

Note:
You are recommended to avoid issuing the following MQI calls in channel-exit programs:

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:

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.

Note:
Before using a channel-exit program for the first time on WebSphere MQ for AIX, iSeries, HP-UX, Solaris, and Windows, and MQSeries V5.1 for Compaq Tru64 UNIX, and OS/2 Warp, you should relink it with threaded libraries to make it thread-safe.

WebSphere MQ for z/OS without CICS

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:

The following exit samples are provided with WebSphere MQ for z/OS:

CSQ4BAX0
This sample is written in assembler, and illustrates the use of MQXWAIT.

CSQ4BCX1  and  CSQ4BCX2
These samples are written in C and illustrate how to access the parameters.

WebSphere MQ for z/OS using CICS

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.

WebSphere MQ for iSeries

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:

MQSeries for OS/2 Warp

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

Windows 3.1 client

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
}

WebSphere MQ for Windows server, WebSphere MQ client for Windows

The exit is a DLL that must be written in C.

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

WebSphere MQ for AIX

Note:
Before you use an existing user exit for the first time on WebSphere MQ for AIX, you must recompile it to enable it to take advantage of thread-safe system calls. If your user exits use thread-unsafe system calls, you will need to modify them before using them on this platform.

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.

Note:
All functions that will be called by WebSphere MQ must be exported.

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)
 

MQSeries for Compaq OpenVMS Alpha

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

MQSeries for Compaq Tru64 UNIX

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

WebSphere MQ for HP-UX

Note:
Before you use an existing user exit for the first time on WebSphere MQ for HP-UX, you must recompile it to enable it to take advantage of thread-safe system calls. If your user exits use thread-unsafe system calls, you will need to modify them before using them on this platform.

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)

MQSeries for AT&T GIS UNIX

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)

WebSphere MQ for Solaris

Note:
Before you use an existing user exit for the first time on WebSphere MQ for Solaris, you must recompile it to enable it to take advantage of thread-safe system calls. If your user exits use thread-unsafe system calls, you will need to modify them before using them on this platform. If you have DCE installed, your channel exits must be threaded with DCE threading. If you do not have DCE installed, your channel exits must be threaded with Posix V10 threading.

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)

MQSeries for SINIX and DC/OSx

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

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:

Building and using channel exit functions

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.

Note:
This procedure modifies the target executable. Therefore, you are recommended to make a backup copy of the target executable or library before using the macro.

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

Sample channel exit
 /********************************************************************/
 /*                                                                  */
 /* 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                                                  */
 /*                                                                  */
 /********************************************************************/

Footnotes:

11
MQMVX.LIB is used for data conversion and is not available on client products.

12
This platform has become NCR UNIX SVR4 MP-RAS, R3.0


© IBM Corporation 2002. All Rights Reserved