PURPOSE
tpcall - routine for sending service request and
awaiting its reply
SYNOPSIS
int tpcall(char *svc, char *idata, long ilen, char **odata, long *olen,
long flags)
DESCRIPTION
tpcall() sends a request and synchronously awaits its reply. A
call to this function is the same as calling tpacall(3c) immediately
followed by tpgetrply(3c).
tpcall() sends a request to the service named by svc. The
request is sent out at the priority defined for svc unless
overridden by a previous call to tpsprio(3c). The data portion of a request is
pointed to by idata, a buffer previously allocated by tpalloc(3c). ilen
specifies how much of idata to send. Note that if idata
points to a buffer of a type that does not require a length to be
specified, (for example, an FML fielded buffer), then ilen
is ignored (and may be 0). Also, idata may be NULL, in
which case ilen is ignored. The type and sub-type of idata
must match one of the types and sub-types recognized by svc.
odata is the address of a pointer to the buffer where a
reply is read into, and olen points to the length of that
reply. *odata must point to a buffer originally allocated
by tpalloc(3c). If the
same buffer is to be used for both sending and receiving, odata
should be set to the address of idata. 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. Also,
if idata and *odata were equal when tpcall() was
invoked, and *odata is changed, then idata no
longer points to a valid address. Using the old address can lead
to data corruption or process exceptions.
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 tpcall
was issued with *olen See intro(3) for more information about the
buffer management.
If *olen is 0 upon return, then the reply has no data
portion and neither *odata nor the buffer it points to
were modified. It is an error for *odata or olen to
be NULL.
Following is a list of valid flags.
- TPNOTRAN
- If the caller is in transaction mode and this flag is
set, then when svc is invoked, it is not performed
on behalf of the caller's transaction. Note that svc
may still be invoked in transaction mode but it will not
be the same transaction: a svc may have as a
configuration attribute that it is automatically invoked
in transaction mode. A caller in transaction mode that
sets this flag is still subject to the transaction
timeout (and no other). If a service fails that was
invoked with this flag, the caller's transaction is not
affected.
- TPNOCHANGE
- By default, if a buffer is received that differs in type
from the buffer pointed to by *odata, then *odata'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 *odata
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 *odata.
- TPNOBLOCK
- The request is not sent if a blocking condition exists
(for example, the internal buffers into which the message
is transferred are full). Note that this flag applies
only to the send portion of tpcall(): the function may
block waiting for the reply. When TPNOBLOCK is
not specified and a blocking condition exists, the caller
blocks until the condition subsides or a timeout occurs
(either transaction or blocking timeout).
- TPNOTIME
- This flag signifies that the caller is willing to block
indefinitely and wants to be immune to blocking timeouts.
However, if the caller is in transaction mode, this flag
has no effect; it is subject to the transaction time-out
limit. Transaction timeouts may still occur.
- TPSIGRSTRT
- If a signal interrupts any underlying system calls, then
the interrupted system call is re-issued.
RETURN VALUES
Upon successful return from tpcall() or upon return where tperrno
is set to TPESVCFAIL, tpurcode contains an
application defined value that was sent as part of tpreturn(3c). tpcall()
returns -1 on error and sets tperrno to indicate the
error condition.
ERRORS
Under the following conditions, tpcall() fails and sets tperrno
to one of the following values. (Unless otherwise noted, failure
does not affect the caller's transaction, if one exists.)
- [TPEINVAL]
- Invalid arguments were given (for example, svc is
NULL or flags are invalid).
- [TPENOENT]
- Can not send to svc because it does not exist or
it is a conversational service or it beings with a
"..".
- [TPEITYPE]
- The type and sub-type of idata is not one of the
allowed types and sub-types that svc accepts.
- [TPEOTYPE]
- Either the type and sub-type of the reply are not known
to the caller; or, TPNOCHANGE was set in flags
and the type and sub-type of *odata do not match
the type and sub-type of the reply sent by the service.
Neither *odata, its contents, nor *olen is
changed. If the service request was made on behalf of the
caller's current transaction, then the transaction is
marked abort-only since the reply is discarded.
- [TPETRAN]
- svc belongs to a server that does not support
transactions and TPNOTRAN was not set.
- [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
was specified. In either case, neither *odata, its
contents, nor *olen is changed. If a transaction
timeout occurred, then with one exception, any attempts
to send new requests or receive outstanding replies will
fail with TPETIME until the transaction has
been aborted. The exception is a request that does not
block, expects no reply, and is not sent on behalf of the
caller's transaction (that is, tpacall() with TPNOTRAN,
TPNOBLOCK, and TPNOREPLY set).
- [TPESVCFAIL]
- The service routine sending the caller's reply called tpreturn(3c) with
TPFAIL. This is an application-level failure.
The contents of the service's reply, if one was sent, is
available in the buffer pointed to by *odata. If
the service request was made on behalf of the caller's
current transaction, then the transaction is marked
abort-only. Note that so long as the transaction has not
timed out, further communication may be performed before
aborting the transaction and that any work performed on
behalf of the caller's transaction will be aborted upon
transaction completion (that is, for subsequent
communication to have any lasting effect, it should be
done with TPNOTRAN set).
- [TPESVCERR]
- A service routine encountered an error either in tpreturn(3c) or tpforward(3c) (for
example, bad arguments were passed). No reply data is
returned when this error occurs (that is, neither *odata,
its contents, nor *olen is changed). If the
service request was made on behalf of the caller's
transaction (that is, TPNOTRAN was not set),
then the transaction is marked abort-only. Note that so
long as the transaction has not timed out, further
communication may be performed before aborting the
transaction and that any work performed on behalf of the
caller's transaction will be aborted upon transaction
completion (that is, for subsequent communication to have
any lasting effect, it should be done with TPNOTRAN
set). If either SVCTIMEOUT in the ubbconfig
file or TA_SVCTIMEOUT in the TM_MIB
are non-zero, TPESVCERR is returned when a
service timeout occurs. In this case, tperrordetail(3)
will return TPED_SVCTIMEOUT.
- [TPEBLOCK]
- A blocking condition was found on the send call and TPNOBLOCK
was specified.
- [TPGOTSIG]
- A signal was received and TPSIGRSTRT was not
specified.
- [TPEPROTO]
- tpcall() was called in an improper context.
- [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. If a message
queue on a remote location is filled, TPEOS
may be returned even if tpcall returned
successfully.
SEE ALSO
tpalloc(3c),
tpacall(3c),
tpforward(3c),
tpfree(3c),
tpgprio(3c),
tprealloc(3c),
tpreturn(3c),
tpsprio(3c),
tperrordetail(3c),
tpstrerrordetail(3c),
tptypes(3c)