PURPOSE
tprecv - routine for receiving a message in a
conversational connection
SYNOPSIS
#include <atmi.h>
int tprecv(int cd, char **data, long *len, long flags, long *revent)
DESCRIPTION
tprecv() is used to receive data sent across an open
connection from another program. tprecv()'s first argument, cd,
specifies on which open connection to receive data. cd is
a descriptor returned from either tpconnect(3c) or the TPSVCINFO
parameter to the service. The second argument, data, is
the address of a pointer to a buffer previously allocated by tpalloc(3c).
data must be the address of a pointer to a buffer
previously allocated by tpalloc(3c)
and len should point to a long that tprecv() sets to the
amount of data successfully received. Upon successful return, *data
points to a buffer containing the reply and *len contains
the size of the buffer. FML and FML32
buffers often assume a minimum size of 4096 bytes; if the reply
is larger than 4096 bytes, the size of the buffer is increased to
a size large enough to accommodate the data being returned.
Buffers on the sending side that may be only partially filled
(for example, FML or STRING buffers) will have only the amount
that is used sent. The system may then enlarge the received data
size by some arbitrary amount. This means that the receiver may
receive a buffer that is smaller than what was originally
allocated by the sender, yet larger than the data that was sent.
The receive buffer may grow, or it may shrink, and its address
almost invariably changes, as the system swaps buffers around
internally. To determine whether (and how much) a reply buffer
changed in size, compare its total size before tprecv
was issued with *len. See intro(3) for more information about buffer
management.
If *len is 0, then no data was received and neither *data
nor the buffer it points to were modified. It is an error for data,
*data or len to be NULL.
tprecv() can be issued only by the program that does not have
control of the connection.
Following is a list of valid flags.
- TPNOCHANGE
- By default, if a buffer is received that differs in type
from the buffer pointed to by *data, then *data's
buffer type changes to the received buffer's type so long
as the receiver recognizes the incoming buffer type. When
this flag is set, the type of the buffer pointed to by *data
is not allowed to change. That is, the type and sub-type
of the received buffer must match the type and sub-type
of the buffer pointed to by *data.
- TPNOBLOCK
- tprecv() does not wait for data to arrive. If data is
already available to receive, then tprecv() gets the data
and returns. When this flag is not specified and no data
is available to receive, the caller blocks until data
arrives.
- TPNOTIME
- This flag signifies that the caller is willing to block
indefinitely and wants to be immune to blocking timeouts.
Transaction timeouts will still affect the program.
- TPSIGRSTRT
- If a signal interrupts the underlying receive system
call, then the call is re-issued.
If an event exists for the descriptor, cd, then
tprecv() will return setting tperrno to TPEEVENT.
The event type is returned in revent. Data can be received
along with the TPEV_SVCSUCC, TPEV_SVCFAIL,
and TPEV_SENDONLY events. Valid events for tprecv()
are as follows.
- TPEV_DISCONIMM
- Received by the subordinate of a conversation, this event
indicates that the originator of the conversation has
either issued an immediate disconnect on the connection
via tpdiscon(3c),
or it issued tpreturn(3c),
tpcommit(3c)
or tpabort() with the connection still open.
This event is also returned to the originator or
subordinate when a connection is broken due to a
communications error (for example, a server, machine, or
network failure). Because this is an immediate
disconnection notification (that is, abortive rather than
orderly), data in transit may be lost. If the two
programs were participating in the same transaction, then
the transaction is marked abort-only. The descriptor used
for the connection is no longer valid.
- TPEV_SENDONLY
- The program on the other end of the connection has
relinquished control of the connection. The recipient of
this event is allowed to send data but can not receive
any data until it relinquishes control.
- TPEV_SVCERR
- Received by the originator of a conversation, this event
indicates that the subordinate of the conversation has
issued tpreturn(3c).
tpreturn(3c)
encountered an error that precluded the service from
returning successfully. For example, bad arguments may
have been passed to tpreturn(3c) or tpreturn(3c) may
have been called while the service had open connections
to other subordinates. Due to the nature of this event,
any application defined data or return code are not
available. The connection has been torn down and cd
is no longer a valid descriptor. If this event occurred
as part of the recipient's transaction, then the
transaction is marked abort-only.
If either SVCTIMEOUT
in the UBBCONFIG file or TA_SVCTIMEOUT
in the TM_MIB are non-zero, the event, TPEV_SVCERR,
is returned when a service timeout occurs. In this case, tperrordetail(3)
will return TPED_SVCTIMEOUT. This event can be
caused by an ACL permissions violation; that is, the
originator does not have permission to connect to the
receiving process. This event is not returned at the time
the tpconnect is issued, but is returned with
the first tpsend (following a tpconnect
with flag TPSENDONLY) or tprecv
(following a tpconnect with flag TPRECVONLY).
A system event and a userlog message are also
generated.
- TPEV_SVCFAIL
- Received by the originator of a conversation, this event
indicates that the subordinate service on the other end
of the conversation has finished unsuccessfully as
defined by the application (that is, it called tpreturn(3c) with
TPFAIL or TPEXIT). If the
subordinate service was in control of this connection
when tpreturn(3c)
was called, then it can pass an application defined
return value and a typed buffer back to the originator of
the connection. As part of ending the service routine,
the server has torn down the connection. Thus, cd
is no longer a valid descriptor. If this event occurred
as part of the recipient's transaction, then the
transaction is marked abort-only.
- TPEV_SVCSUCC
- Received by the originator of a conversation, this event
indicates that the subordinate service on the other end
of the conversation has finished successfully as defined
by the application (that is, it called tpreturn(3c) with
TPSUCCESS). As part of ending the service
routine, the server has torn down the connection. Thus, cd
is no longer a valid descriptor. If the recipient is in
transaction mode, then it can either commit (if it is
also the initiator) or abort the transaction causing the
work done by the server (if also in transaction mode) to
either commit or abort.
RETURN VALUES
Upon return from tprecv() where revent is set to either
TPEV_SVCSUCC or TPEV_SVCFAIL, the tpurcode
global contains an application defined value that was sent as
part of tpreturn(3c).
tprecv() returns -1 on error and sets tperrno to
indicate the error condition.
ERRORS
Under the following conditions, tprecv() fails and sets tperrno
to:
- [TPEINVAL]
- Invalid arguments were given (for example, data is
not the address of a pointer to a buffer allocated by tpalloc(3c) or flags
are invalid).
- [TPEOTYPE]
- Either the type and sub-type of the incoming buffer are
not known to the caller,or TPNOCHANGE was set
in flags and the type and sub-type of *data
do not match the type and sub-type of the incoming
buffer. Regardless, neither *data, its contents
nor *len are changed. If the conversation is part
of the caller's current transaction, then the transaction
is marked abort-only since the incoming buffer is
discarded.
- [TPEBADDESC]
- cd is invalid.
- [TPETIME]
- A timeout occurred. If the caller is in transaction mode,
then a transaction timeout occurred and the transaction
is marked abort-only; otherwise, a blocking timeout
occurred and neither TPNOBLOCK nor TPNOTIME
were specified. In either case, neither *data nor
its contents are changed. If a transaction timeout
occurred, then any attempts to send or receive messages
on any connections or to start a new connection will fail
with TPETIME until the transaction has been
aborted.
- [TPEEVENT]
- An event occurred and its type is available in revent.
There is a relationship between the [TPETIME]
and the [TPEEVENT] return codes. While in
transaction mode, if the receiving side of a conversation
is blocked on tprecv and the sending side
calls tpabort, then the receiving side gets a
return code of [TPEVENT] with an event of TPEV_DISCONIMM.
However, if the sending side calls tpabort
before the receiving side calls tprecv, then
the transaction may have already been removed from the
GTT, which causes tprecv to fail with the [TPETIME]
code.
- [TPEBLOCK]
- A blocking condition exists and TPNOBLOCK was
specified.
- [TPGOTSIG]
- A signal was received and TPSIGRSTRT was not
specified.
- [TPEPROTO]
- tprecv() was called in an improper context (for example,
the connection was established such that the calling
program can only send data).
- [TPESYSTEM]
- A System/T error has occurred. The exact nature of the
error is written to a log file.
- [TPEOS]
- An operating system error has occurred.
USAGE
A server can pass an application defined return value and
typed buffer when calling tpreturn(3c).
The return value is available in the global variable tpurcode
and the buffer is available in data.
SEE ALSO
tpalloc(3c),
tpconnect(3c),
tpdiscon(3c),
tpsend(3c),
tpservice(3c)