Occasionally, there is a need to receive messages from the job log that are sent to a call message queue that is no longer active.
For example, PGMA calls PGMB and PGMB sends a diagnostic message to itself and an escape message to PGMA. PGMA can easily receive the escape message that was sent to it, but sometimes it is necessary to also receive the diagnostic message. Because the diagnostic is on a call message queue that is no longer active, the message must be received by using a message reference key. This can be done, but it takes more work than one simple receive message command.
The following considerations are important in understanding how this works:
The following steps are required to obtain a message from a program or procedure that has ended:
A sample program of the procedure described previously is provided as follows using the RCVMSG command and the QMHRCVPM API.
*******************************************************************************
*
* CL program example using the RCVMSG command
*
*
*******************************************************************************
This has the advantage of being easier to code and is easier to follow.
It has the disadvantage of requiring the program to monitor for and handle
the CPF2410 exception, which is not a good thing if performance is important.
PGM
DCL &LOWKEY *CHAR 4
DCL &HIKEY *CHAR 4
DCL &MSGKEY *CHAR 4
DCL &MSG *CHAR 256
/*-----------------------------------------------------------------*/
/* OBTAIN STARTING MESSAGE REFERENCE KEY */
/*-----------------------------------------------------------------*/
SNDPGMMSG MSG(TEST) TOPGMQ(*SAME) KEYVAR(&LOWKEY)
RMVMSG MSGKEY(&LOWKEY)
/*-----------------------------------------------------------------*/
/* EXECUTE FUNCTION */
/*-----------------------------------------------------------------*/
---- Insert whatever command(s) or program call(s) you want ----
---- to handle messages for here ----
/*-----------------------------------------------------------------*/
/* OBTAIN ENDING MESSAGE REFERENCE KEY */
/*-----------------------------------------------------------------*/
SNDPGMMSG MSG(TEST) TOPGMQ(*SAME) KEYVAR(&HIKEY)
RMVMSG MSGKEY(&HIKEY)
/*-----------------------------------------------------------------*/
/* LOOP TO RECEIVE MESSAGES ON INACTIVE INVOCATION */
/*-----------------------------------------------------------------*/
CHGVAR %BIN(&MSGKEY 1 4) (%BIN(&LOWKEY 1 4) + 1)
LOOP:
RCVMSG PGMQ(*SAME (*)) MSGKEY(&MSGKEY) RMV(*NO) MSG(&MSG)
MONMSG CPF2410 EXEC(DO) /* HANDLE MSGKEY NOT FOUND */
RCVMSG MSGTYPE(*EXCP) RMV(*YES) /* REMOVE UNWANTED EXCEPTION */
GOTO SKIP
ENDDO
---- Insert code here to do whatever processing is needed ----
---- for the message. You may need to add additional ----
---- values, such as message ID, message type, etc., to ----
---- the RCVMSG command. ----
SKIP:
CHGVAR %BIN(&MSGKEY 1 4) (%BIN(&MSGKEY 1 4) + 1)
IF (&MSGKEY *LT &HIKEY) GOTO LOOP
ENDPGM
*******************************************************************************
*
* CL program using the QMHRCVPM API.
*
*******************************************************************************
This sample is similar to the first sample. The only difference is that
it uses the QMHRCVPM API instead of the RCVMSG CL command. By using the error
code structure, it eliminates the need to handle the CPF2410 exception and the
overhead required to send the exception in the case of the message key not
being found. This example shows how to extract the message text from the
structure returned by the API. If the message is an immediate message (i.e. no
message ID), the message is in the 'Replacement data or impromptu message text'
area; otherwise it is in the 'Message' area which follows the 'Replacement
data' field. The example checks the message length to determine which of these
fields to use for the message.
PGM
DCL &LOWKEY *CHAR 4
DCL &HIKEY *CHAR 4
DCL &MSGKEY *CHAR 4
DCL &MSG *CHAR 256
/*------------------------------------------------------------------*/
/* Some messages have a large amount of message data, in which case */
/* the size of the &MSGINFO variable will not be adequate. If you */
/* expect to receive messages with a large amount of message data, */
/* you will need to increase the size of this variable accordingly. */
/* Be sure to also change the value that is put into &MSGINFOL to */
/* reflect the size of the variable. */
/*------------------------------------------------------------------*/
DCL &MSGINFO *CHAR 1000
DCL &MSGINFOL *CHAR 4
DCL &ERRCODE *CHAR 16
DCL &MSGOFFS *DEC (4 0)
DCL &MSGLEN *DEC (4 0)
/*-----------------------------------------------------------------*/
/* OBTAIN STARTING MESSAGE REFERENCE KEY */
/*-----------------------------------------------------------------*/
SNDPGMMSG MSG(TEST) TOPGMQ(*SAME) KEYVAR(&LOWKEY)
RMVMSG MSGKEY(&LOWKEY)
/*-----------------------------------------------------------------*/
/* EXECUTE FUNCTION */
/*-----------------------------------------------------------------*/
---- Insert whatever command(s) or program call(s) you want ----
---- to handle messages for here ----
/*-----------------------------------------------------------------*/
/* OBTAIN ENDING MESSAGE REFERENCE KEY */
/*-----------------------------------------------------------------*/
SNDPGMMSG MSG(TEST) TOPGMQ(*SAME) KEYVAR(&HIKEY)
RMVMSG MSGKEY(&HIKEY)
/*-----------------------------------------------------------------*/
/* LOOP TO RECEIVE MESSAGES WITH QMHRCVPM API */
/*-----------------------------------------------------------------*/
CHGVAR %BIN(&MSGKEY 1 4) (%BIN(&LOWKEY 1 4) + 1)
CHGVAR %BIN(&MSGINFOL 1 4) 1000
CHGVAR %BIN(&ERRCODE 1 4) 16
LOOP2:
CALL QMHRCVPM (&MSGINFO &MSGINFOL RCVM0200 '* ' +
X'00000000' '*ANY ' &MSGKEY X'00000000' +
'*SAME ' &ERRCODE)
IF ((%BIN(&MSGINFO 5 4) *GT 0) *AND (%BIN(&ERRCODE 5 4) *EQ 0)) +
DO /* IF A MESSAGE WAS RECEIVED */
IF (%BIN(&MSGINFO 161 4) *EQ 0) +
DO /* IMPROMPTU MESSAGE */
CHGVAR &MSGLEN %BIN(&MSGINFO 153 4)
CHGVAR &MSGOFFS 177
ENDDO
ELSE +
DO /* STORED MESSAGE */
CHGVAR &MSGLEN %BIN(&MSGINFO 161 4)
CHGVAR &MSGOFFS (177 + %BIN(&MSGINFO 153 4))
ENDDO
CHGVAR &MSG %SST(&MSGINFO &MSGOFFS &MSGLEN)
---- Insert code here to do whatever processing is needed ----
---- for the message. You can extract additional ----
---- values, such as message ID, message type, etc., ----
---- from the message information structure if necessary. ----
ENDDO
CHGVAR %BIN(&MSGKEY 1 4) (%BIN(&MSGKEY 1 4) + 1)
IF (&MSGKEY *LT &HIKEY) GOTO LOOP2
ENDPGM