Implementing a read/write interface
Sometimes you may want to establish a transport connection and then
exec(S)
an existing user program such as
cat(C)
to process the data as it arrives over the connection.
However, most existing programs use
read(S)
and
write(S)
to perform character I/O.
XTI and TLI do not directly
support a read/write interface
to a transport provider, but one may be provided using the
tirdwr(M)
STREAMS module. (This module is present in
the kernel by default.) Such a connection can be released with the
close(S)
system call.
This interface enables an application to issue read and
write calls over a transport connection that has been
established by the server's call to
t_accept(NET).
NOTE:
This interface is not available with the connectionless-mode service.
In the following example, a server first pushes tirdwr onto a stream
before running
cat(C)
so that a client can read from or write to it over the transport connection.
#include <stropts.h>
. /*
. * connection requested and accepted
. */
if (ioctl(fd, I_PUSH, "tirdwr") < 0) {
perror("I_PUSH of tirdwr failed");
exit(5);
}
close(0);
dup(fd);
execl("/bin/cat", "/bin/cat", 0);
perror("execl of /bin/cat failed");
exit(6);
The server invokes the read/write
interface by pushing the tirdwr
module onto the stream head associated with the transport endpoint
created when the connection was established. For a description of
I_PUSH, see
streamio(M).
With tirdwr in place, the server calls close and
dup(S)
to establish the transport endpoint as its standard input, and
uses cat to process the input.
Because the transport layer is implemented using STREAMS,
the facilities of this character I/O mechanism can be used to provide
enhanced user services. Note the following limitations on the use of
this interface:
-
The semantics of read and write must be followed,
and message boundaries are not preserved.
-
The tirdwr module can be pushed onto a stream only when a connection
has been established and a transport endpoint created.
-
Once the tirdwr module has been pushed, XTI and
TLI routines cannot be invoked on the transport endpoint.
If such a routine is invoked, tirdwr generates the fatal
protocol error, EPROTO, on the stream, rendering it unusable.
-
If tirdwr is popped off the stream
(see I_POP in
streamio(M)),
the transport connection will be aborted.
-
If an application attempts to send a zero-length data packet (which is
allowed by STREAMS), tirdwr will discard the message.
-
If the transport connection is aborted (for example, the client calls
t_snddis(NET)),
a STREAMS hangup condition will be generated.
Further write calls will fail and set
ENXIO in errno.
The application can still retrieve any available data after a hangup.
-
read cannot process expedited data because it cannot distinguish such
data from other data on the stream. If an expedited data indication
is received, tirdwr generates a fatal protocol error,
EPROTO, on the stream.
This error causes further system calls to fail. For this
reason, this interface should not be used to communicate with a
process that can send expedited data.
-
If an abortive disconnect indication is received, tirdwr discards the
indication and generates a STREAMS hangup condition on that stream.
Subsequent read calls retrieve any remaining data, and then read
returns zero for all further calls indicating EOF (end-of-file).
-
If an orderly release indication is received, tirdwr discards the
indication and delivers a zero-length STREAMS message to the user.
As described in
read(S),
this notifies an EOF by returning 0.
If tirdwr receives any other XTI or
TLI indication, it normally
generates a fatal protocol error, EPROTO, on the stream.
This causes further system calls to fail.
However, if tirdwr is pushed onto a stream after a connection
has been established, such indications are not generated.
With tirdwr pushed onto a stream, an application can send and receive
data over the transport connection for the duration of the connection.
Either end of a connection can terminate it by closing the file
descriptor associated with the transport endpoint or by popping the
tirdwr module off the stream.
In either case, tirdwr takes the following actions:
-
If tirdwr previously received an orderly release indication, it passes
an orderly release request to the transport provider to complete the
orderly release of the connection. The end of the connection that
initiated the orderly release receives the expected indication when
data transfer completes.
NOTE:
A process cannot initiate an orderly release after it has
pushed tirdwr onto a stream.
In this case, tirdwr can handle an
orderly release if it was initiated from the opposite side of a
transport connection.
-
If tirdwr previously received a disconnect indication, it takes no
special action.
-
If tirdwr did not previously receive an orderly release indication or
disconnect indication, it passes a disconnect request to the transport
provider to abort the connection.
-
If an error previously occurred on the stream and tirdwr did not
receive a disconnect indication, it passes a disconnect request to the
transport provider.
Next topic:
For more about XTI and TLI
Previous topic:
Server pseudo-code
© 2003 Caldera International, Inc. All rights reserved.
SCO OpenServer Release 5.0.7 -- 11 February 2003