 |
HP OpenVMS Programming Concepts Manual
3.2.2.3 Assigning an I/O Channel Along with a Mailbox
A mailbox is a virtual device used for communication between processes.
A channel is the communication path that a process uses to perform I/O
operations to a particular device. The LIB$ASN_WTH_MBX routine assigns
a channel to a device and associates a mailbox with the device.
Normally, a process calls the SYS$CREMBX system service to create a
mailbox and assign a channel and logical name to it. In the case of a
temporary mailbox, this service places the logical name corresponding
to the mailbox in the job logical name table. This implies that any
process running in the same job and using the same logical name uses
the same mailbox.
Sometimes it is not desirable to have more than one process use the
same mailbox. For example, when a program connects explicitly with
another process across a network, the program uses a mailbox both to
obtain the data confirming the connection and to store the asynchronous
messages from the other process. If that mailbox is shared with other
processes in the same group, there is no way to determine which
messages are intended for which processes; the processes read each
other's messages, and the original program does not receive the correct
information from the cooperating process across the network link.
The LIB$ASN_WTH_MBX routine avoids this situation by associating the
physical mailbox name with the channel assigned to the device. To
create a temporary mailbox for itself and other processes cooperating
with it, your program calls LIB$ASN_WTH_MBX. The run-time library
routine assigns the channel and creates the temporary mailbox by using
the system services $GETDVI, $ASSIGN, and $CREMBX. Instead of a logical
name, the mailbox is identified by a physical device name of the form
MBcu. The elements that make up this device name are as
follows:
MB
|
indicates that the device is a mailbox.
|
c
|
is the controller.
|
u
|
is the unit number.
|
The routine returns this device name to the calling program, which then
must pass the mailbox channel to the other programs with which it
cooperates. In this way, the cooperating processes access the mailbox
by its physical name instead of by its jobwide logical name.
The calling program passes the routine a device name, which specifies
the device to which the channel is to be assigned. For this argument
(called dev-nam), you can use a logical name. If you
do so, the routine attempts one level of logical name translation.
The privilege restrictions and process quotas required for using this
routine are those required by the $GETDVI, $CREMBX, and $ASSIGN system
services.
3.2.2.4 Reading and Writing Data to a Mailbox
The following list describes the three ways you can read and write to a
mailbox:
- Synchronous I/O---Reads or writes to a mailbox and then waits for
the cooperating image to perform the other operation. Use I/O
statements for your programming language. This is the recommended
method of addressing a mailbox.
- Immediate I/O---Queues a read or write operation to a mailbox and
continues program execution after the operation completes. To do this,
use the SYS$QIOW system service.
- Asynchronous I/O---Queues a read or write operation to a mailbox
and continues program execution while the request executes. To do this,
use the SYS$QIO system service. When the read or write operation
completes, the I/O status block (if specified) is filled, the event
flag (if specified) is set, and the AST routine (if specified) is
executed.
Chapter 23 describes the SYS$QIO and SYS$QIOW system services and
provides further discussion of mailbox I/O. See the HP OpenVMS System Services Reference Manual for
more information. HP recommends that you supply the optional I/O status
block parameter when you use these two system services. The contents of
the status block varies depending on the QIO function code; refer to
the function code descriptions in the HP OpenVMS I/O User's Reference Manual for a description
of the appropriate status block.
3.2.2.5 Using Synchronous Mailbox I/O
Use synchronous I/O when you read or write information to another image
and cannot continue until that image responds.
The program segment shown in Example 3-2 opens a mailbox for the
first time. To open a mailbox for Fortran I/O, use the OPEN statement
with the following specifiers: UNIT, FILE, CARRIAGECONTROL, and STATUS.
The value for the keyword FILE should be the logical name of a mailbox
(SYS$CREMBX allows you to associate a logical name with a mailbox when
the mailbox is created). The value for the keyword CARRIAGECONTROL
should be 'LIST'. The value for the keyword STATUS should be 'NEW' for
the first OPEN statement and 'OLD' for subsequent OPEN statements.
Example 3-2 Opening a Mailbox |
! Status variable and values
INTEGER STATUS
! Logical unit and name for mailbox
INTEGER MBX_LUN
CHARACTER(*) MBX_NAME
PARAMETER (MBX_NAME = MAIL_BOX)
! Create mailbox
STATUS = SYS$CREMBX (,
2 MBX_CHAN, ! Channel
2 ,,,,
2 MBX_NAME) ! Logical name
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
! Get logical unit for mailbox and open mailbox
STATUS = LIB$GET_LUN (MBX_LUN)
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
OPEN (UNIT = MBX_LUN,
2 FILE = MBX_NAME,
2 CARRIAGECONTROL = 'LIST',
2 STATUS = 'NEW')
|
In Example 3-3, one image passes device names to a second image. The
second image returns the process name and the terminal associated with
the process that allocated each device. A WRITE statement in the first
image does not complete until the cooperating process issues a READ
statement. (The variable declarations are not shown in the second
program because they are very similar to those in the first program.)
Example 3-3 Synchronous I/O Using a
Mailbox |
! DEVICE.FOR
PROGRAM PROCESS_DEVICE
! Status variable
INTEGER STATUS
! Name and I/O channel for mailbox
CHARACTER*(*) MBX_NAME
PARAMETER (MBX_NAME = 'MAIL_BOX')
INTEGER*2 MBX_CHAN
! Logical unit number for FORTRAN I/O
INTEGER MBX_LUN
! Character string format
CHARACTER*(*) CHAR_FMT
PARAMETER (CHAR_FMT = '(A50)')
! Mailbox message
CHARACTER*50 MBX_MESSAGE
.
.
.
! Create the mailbox
STATUS = SYS$CREMBX (,
2 MBX_CHAN, ! Channel
2 ,,,,
2 MBX_NAME) ! Logical name
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
! Get logical unit for mailbox and open mailbox
STATUS = LIB$GET_LUN (MBX_LUN)
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
OPEN (UNIT = MBX_LUN,
2 FILE = MBX_NAME,
2 CARRIAGECONTROL = 'LIST',
2 STATUS = 'NEW')
! Create subprocess to execute GETDEVINF.EXE
STATUS = SYS$CREPRC (,
2 'GETDEVINF', ! Image
2 ,,,,,
2 'GET_DEVICE', ! Process name
2 %VAL(4),,,) ! Priority
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
! Pass device names to GETDEFINF
WRITE (UNIT=MBX_LUN,
2 FMT=CHAR_FMT) 'SYS$DRIVE0'
! Read device information from GETDEFINF
READ (UNIT=MBX_LUN,
2 FMT=CHAR_FMT) MBX_MESSAGE
.
.
.
END
|
GETDEVINF.FOR
.
.
.
! Create mailbox
STATUS = SYS$CREMBX (,
2 MBX_CHAN, ! I/O channel
2 ,,,,
2 MBX_NAME) ! Mailbox name
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
! Get logical unit for mailbox and open mailbox
STATUS = LIB$GET_LUN (MBX_LUN)
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
OPEN (UNIT=MBX_LUN,
2 FILE=MBX_NAME,
2 CARRIAGECONTROL='LIST',
2 STATUS = 'OLD')
! Read device names from mailbox
READ (UNIT=MBX_LUN,
2 FMT=CHAR_FMT) MBX_MESSAGE
! Use SYS$GETJPI to find process and terminal
! Process name: PROC_NAME (1:P_LEN)
! Terminal name: TERM (1:T_LEN)
.
.
.
MBX_MESSAGE = MBX_MESSAGE//' '//
2 PROC_NAME(1:P_LEN)//' '//
2 TERM(1:T_LEN)
! Write device information to DEVICE
WRITE (UNIT=MBX_LUN,
2 FMT=CHAR_FMT) MBX_MESSAGE
END
|
3.2.2.6 Using Immediate Mailbox I/O
Use immediate I/O to send or receive a message from another process
without waiting for a response from that process. To ensure that the
other process receives the information that you write, either do not
exit until the other process has a channel to the mailbox, or use a
permanent mailbox.
Queueing an Immmediate I/O Request
To queue an immediate I/O request, invoke the SYS$QIOW system service.
See the HP OpenVMS System Services Reference Manual for more information.
Reading Data from the Mailbox
Since immediate I/O is asynchronous, a mailbox may contain more than
one message or no message when it is read. If the mailbox contains more
than one message, the read operation retrieves the messages one at a
time in the order in which they were written. If the mailbox contains
no message, the read operation generates an end-of-file error.
To allow a cooperating program to differentiate between an empty
mailbox and the end of the data being transferred, the process writing
the messages should use the IO$_WRITEOF function code to write an
end-of-file message to the mailbox as the last piece of data. When the
cooperating program reads an empty mailbox, the end-of-file message is
returned and the second longword of the I/O status block is 0. When the
cooperating program reads an end-of-file message explicitly written to
the mailbox, the end-of-file message is returned and the second
longword of the I/O status block contains the process identification
number of the process that wrote the message to the mailbox.
In Example 3-4, the first program creates a mailbox named MAIL_BOX,
writes data to it, and then indicates the end of the data by writing an
end-of-file message. The second program creates a mailbox with the same
logical name, reads the messages from the mailbox into an array, and
stops the read operations when a read operation generates an
end-of-file message and the second longword of the I/O status block is
nonzero, confirming that the writing process sent the end-of-file
message. The processes use common event flag 64 to ensure that SEND.FOR
does not exit until RECEIVE.FOR has established a channel to the
mailbox. (If RECEIVE.FOR executes first, an error occurs because
SYS$ASSIGN cannot find the mailbox.)
Example 3-4 Immediate I/O Using a Mailbox |
!SEND.FOR
.
.
.
INTEGER*4 STATUS
! Name and channel number for mailbox
CHARACTER*(*) MBX_NAME
PARAMETER (MBX_NAME = 'MAIL_BOX')
INTEGER*2 MBX_CHAN
! Mailbox message
CHARACTER*80 MBX_MESSAGE
INTEGER LEN
CHARACTER*80 MESSAGES (255)
INTEGER MESSAGE_LEN (255)
INTEGER MAX_MESSAGE
PARAMETER (MAX_MESSAGE = 255)
! I/O function codes and status block
INCLUDE '($IODEF)'
INTEGER*4 WRITE_CODE
STRUCTURE /STATUS_BLOCK/
INTEGER*2 IOSTAT,
2 MSG_LEN
INTEGER*4 READER_PID
END STRUCTURE
RECORD /STATUS_BLOCK/ IOSTATUS
! System routines
INTEGER SYS$CREMBX,
2 SYS$ASCEFC,
2 SYS$WAITFR,
2 SYS$QIOW
! Create the mailbox
STATUS = SYS$CREMBX (,
2 MBX_CHAN,
2 ,,,,
2 MBX_NAME)
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
! Fill MESSAGES array
.
.
.
! Write the messages
DO I = 1, MAX_MESSAGE
WRITE_CODE = IO$_WRITEVBLK .OR. IO$M_NOW
MBX_MESSAGE = MESSAGES(I)
LEN = MESSAGE_LEN(I)
STATUS = SYS$QIOW (,
2 %VAL(MBX_CHAN), ! Channel
2 %VAL(WRITE_CODE), ! I/O code
2 IOSTATUS, ! Status block
2 ,,
2 %REF(MBX_MESSAGE), ! P1
2 %VAL(LEN),,,,) ! P2
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
IF (.NOT. IOSTATUS.IOSTAT)
2 CALL LIB$SIGNAL (%VAL(IOSTATUS.STATUS))
END DO
! Write end-of-file
WRITE_CODE = IO$_WRITEOF .OR. IO$M_NOW
STATUS = SYS$QIOW (,
2 %VAL(MBX_CHAN), ! Channel
2 %VAL(WRITE_CODE), ! End-of-file code
2 IOSTATUS, ! Status block
2 ,,,,,,,)
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
IF (.NOT. IOSTATUS.IOSTAT)
2 CALL LIB$SIGNAL (%VAL(IOSTATUS.IOSTAT))
.
.
.
! Make sure cooperating process can read the information
! by waiting for it to assign a channel to the mailbox
STATUS = SYS$ASCEFC (%VAL(64),
2 'CLUSTER',,)
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
STATUS = SYS$WAITFR (%VAL(64))
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
END
|
RECEIVE.FOR
INTEGER STATUS
INCLUDE '($IODEF)'
INCLUDE '($SSDEF)'
! Name and channel number for mailbox
CHARACTER*(*) MBX_NAME
PARAMETER (MBX_NAME = 'MAIL_BOX')
INTEGER*2 MBX_CHAN
! QIO function code
INTEGER READ_CODE
! Mailbox message
CHARACTER*80 MBX_MESSAGE
INTEGER*4 LEN
! Message arrays
CHARACTER*80 MESSAGES (255)
INTEGER*4 MESSAGE_LEN (255)
! I/O status block
STRUCTURE /STATUS_BLOCK/
INTEGER*2 IOSTAT,
2 MSG_LEN
INTEGER*4 READER_PID
END STRUCTURE
RECORD /STATUS_BLOCK/ IOSTATUS
! System routines
INTEGER SYS$ASSIGN,
2 SYS$ASCEFC,
2 SYS$SETEF,
2 SYS$QIOW
! Create the mailbox and let the other process know
STATUS = SYS$ASSIGN (MBX_NAME,
2 MBX_CHAN,,,)
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
STATUS = SYS$ASCEFC (%VAL(64),
2 'CLUSTER',,)
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
STATUS = SYS$SETEF (%VAL(64))
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
! Read first message
READ_CODE = IO$_READVBLK .OR. IO$M_NOW
LEN = 80
STATUS = SYS$QIOW (,
2 %VAL(MBX_CHAN), ! Channel
2 %VAL(READ_CODE), ! Function code
2 IOSTATUS, ! Status block
2 ,,
2 %REF(MBX_MESSAGE), ! P1
2 %VAL(LEN),,,,) ! P2
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
IF ((.NOT. IOSTATUS.IOSTAT) .AND.
2 (IOSTATUS.IOSTAT .NE. SS$_ENDOFFILE)) THEN
CALL LIB$SIGNAL (%VAL(IOSTATUS.IOSTAT))
ELSE IF (IOSTATUS.IOSTAT .NE. SS$_ENDOFFILE) THEN
I = 1
MESSAGES(I) = MBX_MESSAGE
MESSAGE_LEN(I) = IOSTATUS.MSG_LEN
END IF
! Read messages until cooperating process writes end-of-file
DO WHILE (.NOT. ((IOSTATUS.IOSTAT .EQ. SS$_ENDOFFILE) .AND.
2 (IOSTATUS.READER_PID .NE. 0)))
STATUS = SYS$QIOW (,
2 %VAL(MBX_CHAN), ! Channel
2 %VAL(READ_CODE), ! Function code
2 IOSTATUS, ! Status block
2 ,,
2 %REF(MBX_MESSAGE), ! P1
2 %VAL(LEN),,,,) ! P2
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
IF ((.NOT. IOSTATUS.IOSTAT) .AND.
2 (IOSTATUS.IOSTAT .NE. SS$_ENDOFFILE)) THEN
CALL LIB$SIGNAL (%VAL(IOSTATUS.IOSTAT))
ELSE IF (IOSTATUS.IOSTAT .NE. SS$_ENDOFFILE) THEN
I = I + 1
MESSAGES(I) = MBX_MESSAGE
MESSAGE_LEN(I) = IOSTATUS.MSG_LEN
END IF
END DO
.
.
.
|
3.2.2.7 Using Asynchronous Mailbox I/O
Use asynchronous I/O to queue a read or write request to a mailbox. To
ensure that the other process receives the information you write,
either do not exit the other process until the other process has a
channel to the mailbox, or use a permanent mailbox.
To queue an asynchronous I/O request, invoke the SYS$QIO system
service; however, when specifying the function codes, do not specify
the IO$M_NOW modifier. The SYS$QIO system service allows you to specify
either an AST to be executed or an event flag to be set when the I/O
operation completes.
Example 3-5 calculates gross income and taxes and then uses the
results to calculate net income. INCOME.FOR uses SYS$CREPRC, specifying
a termination mailbox, to create a subprocess to calculate taxes
(CALC_TAXES) while INCOME calculates gross income. INCOME issues an
asynchronous read to the termination mailbox, specifying an event flag
to be set when the read completes. (The read completes when CALC_TAXES
completes, terminating the created process and causing the system to
write to the termination mailbox.) After finishing its own gross income
calculations, INCOME.FOR waits for the flag that indicates CALC_TAXES
has completed and then figures net income.
CALC_TAXES.FOR passes the tax information to INCOME.FOR using the
installed common block created from INSTALLED.FOR.
Example 3-5 Asynchronous I/O Using a
Mailbox |
!INSTALLED.FOR
! Installed common block to be linked with INCOME.FOR and
! CALC_TAXES.FOR.
! Unless the shareable image created from this file is
! in SYS$SHARE, you must define a group logical name
! INSTALLED and equivalence it to the full file specification
! of the shareable image.
INTEGER*4 INCOME (200),
2 TAXES (200),
2 NET (200)
COMMON /CALC/ INCOME,
2 TAXES,
2 NET
END
|
!INCOME.FOR
! Status and system routines
.
.
.
INCLUDE '($SSDEF)'
INCLUDE '($IODEF)'
INTEGER STATUS,
2 LIB$GET_LUN,
2 LIB$GET_EF,
2 SYS$CLREF,
2 SYS$CREMBX,
2 SYS$CREPRC,
2 SYS$GETDVIW,
2 SYS$QIO,
2 SYS$WAITFR
! Set up for SYS$GETDVI
! Define itmlst structure
STRUCTURE /ITMLST/
UNION
MAP
INTEGER*2 BUFLEN
INTEGER*2 CODE
INTEGER*4 BUFADR
INTEGER*4 RETLENADR
END MAP
MAP
INTEGER*4 END_LIST
END MAP
END UNION
END STRUCTURE
! Declare itmlst
RECORD /ITMLST/ DVILIST (2)
INTEGER*4 UNIT_BUF,
2 UNIT_LEN
EXTERNAL DVI$_UNIT
! Name and I/O channel for mailbox
CHARACTER*(*) MBX_NAME
PARAMETER (MBX_NAME = 'MAIL_BOX')
INTEGER*2 MBX_CHAN
INTEGER*4 MBX_LUN ! Logical unit number for I/O
CHARACTER*84 MBX_MESSAGE ! Mailbox message
INTEGER*4 READ_CODE,
2 LENGTH
! I/O status block
STRUCTURE /STATUS_BLOCK/
INTEGER*2 IOSTAT,
2 MSG_LEN
INTEGER*4 READER_PID
END STRUCTURE
RECORD /STATUS_BLOCK/ IOSTATUS
! Declare calculation variables in installed common
INTEGER*4 INCOME (200),
2 TAXES (200),
2 NET (200)
COMMON /CALC/ INCOME,
2 TAXES,
2 NET
! Flag to indicate taxes calculated
INTEGER*4 TAX_DONE
! Get and clear an event flag
STATUS = LIB$GET_EF (TAX_DONE)
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
STATUS = SYS$CLREF (%VAL(TAX_DONE))
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
! Create the mailbox
STATUS = SYS$CREMBX (,
2 MBX_CHAN,
2 ,,,,
2 MBX_NAME)
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
! Get unit number of the mailbox
DVILIST(1).BUFLEN = 4
DVILIST(1).CODE = %LOC(DVI$_UNIT)
DVILIST(1).BUFADR = %LOC(UNIT_BUF)
DVILIST(1).RETLENADR = %LOC(UNIT_LEN)
DVILIST(2).END_LIST = 0
STATUS = SYS$GETDVIW (,
2 %VAL(MBX_CHAN), ! Channel
2 MBX_NAME, ! Device
2 DVILIST, ! Item list
2 ,,,)
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
! Create subprocess to calculate taxes
STATUS = SYS$CREPRC (,
2 'CALC_TAXES', ! Image
2 ,,,,,
2 'CALC_TAXES', ! Process name
2 %VAL(4), ! Priority
2 ,
2 %VAL(UNIT_BUF),)
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
! Asynchronous read to termination mailbox
! sets flag when tax calculations complete
READ_CODE = IO$_READVBLK
LENGTH = 84
STATUS = SYS$QIO (%VAL(TAX_DONE), ! Indicates read complete
2 %VAL(MBX_CHAN), ! Channel
2 %VAL(READ_CODE), ! Function code
2 IOSTATUS,,, ! Status block
2 %REF(MBX_MESSAGE),! P1
2 %VAL(LENGTH),,,,) ! P2
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
! Calculate incomes
.
.
.
! Wait until taxes are calculated
STATUS = SYS$WAITFR (%VAL(TAX_DONE))
IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
! Check mailbox I/O
IF (.NOT. IOSTATUS.IOSTAT)
2 CALL LIB$SIGNAL (%VAL(IOSTATUS.IOSTAT))
! Calculate net income after taxes
.
.
.
END
|
CALC_TAXES.FOR
! Declare calculation variables in installed common
INTEGER*4 INCOME (200),
2 TAXES (200),
2 NET (200)
COMMON /CALC/ INCOME,
2 TAXES,
2 NET
! Calculate taxes
.
.
.
END
|
3.3 Intracluster Communication
Intracluster communication (ICC), available through ICC system
services, forms an application program interface (API) for
process-to-process communications. For large data transfers,
intracluster communication is the highest performance OpenVMS
application communication mechanism, better than standard network
transports and mailboxes.
Intracluster communication enables application program developers to
create distributed applications with connections between different
processes on a single system or between processes on different systems
within a single OpenVMS Cluster system. Intracluster communication does
not require a network product. It uses memory or System Communication
Services (SCS).
The intracluster system services used to implement intracluster
communication do the following:
- Allow the creation of both client and server processes
- Maintain a simple registry of servers and services
- Manage security of the server process namespace and access to
server processes
- Establish connections between these processes and transmit data
between these processes
- Provide 64-bit buffer and address support
Intracluster system services provide the following benefits when
implementing ICC:
- An easy-to-use conventional system service interface for
interprocess communications within a cluster
- An interface usable for communications between processes within a
single, nonclustered node
- An interface callable from all modes and from execlets as well as
from images
- An easy-to-use interface giving access to high-speed interconnects
such as Memory Channel
- An interface independent of the installation of any networking
product
- An interface usable for nonprivileged clients and authorized (but
not necessarily privileged) servers
The intracluster communication system services are as follows:
- Open Association: SYS$ICC_OPEN_ASSOC
- Close Association: SYS$ICC_CLOSE_ASSOC
- Connect: SYS$ICC_CONNECT and SYS$ICC_CONNECTTW
- Accept: SYS$ICC_ACCEPT
- Reject: SYS$ICC_REJECT
- Disconnect: SYS$ICC_DISCONNECT and SYS$ICC_DISCONNECTW
- Transmit Data: SYS$ICC_TRANSMIT and SYS$ICC_TRANSMITW
- Receive Data: SYS$ICC_RECEIVE and SYS$ICC_RECEIVEW
- Transceive Data: SYS$ICC_TRANSCEIVE and SYS$ICC_TRANSCEIVEW
- Reply: SYS$ICC_REPLY and SYS$ICC_REPLYW
See the HP OpenVMS System Services Reference Manual: GETUTC--Z for additional information about the ICC system
services.
|