PURPOSE

tprecv - routine for receiving a message in a conversational connection

SYNOPSIS

#include &ltatmi.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)