Network Interface Guide

Read/Write Interface

A user might want to establish a transport connection using exec(2) on an existing program (such as /usr/bin/cat) to process the data as it arrives over the connection. Existing programs use read(2) and write(2). XTI/TLI does not directly support a read/write interface to a transport provider, but one is available. The interface lets you issue read(2) and write(2) calls over a transport connection in the data transfer phase. This section describes the read/write interface to the connection mode service of XTI/TLI. This interface is not available with the connectionless mode service.

The read/write interface is presented using the client example (with modifications) of "Connection Mode Service". The clients are identical until the data transfer phase. Then the client uses the read/write interface and cat(1) to process incoming data. cat(1) is run without change over the transport connection. Only the differences between this client and that of the client in Example 3-3are shown in Example 3-8.

Example 3-8 Read/Write Interface

#include <stropts.h>
     Same local management and connection establishment steps.
   if (ioctl(fd, I_PUSH, "tirdwr") == -1) {
      perror("I_PUSH of tirdwr failed");
   execl("/usr/bin/cat", "/usr/bin/cat", (char *) 0);
   perror("exec of /usr/bin/cat failed");

The client invokes the read/write interface by pushing tirdwr onto the stream associated with the transport endpoint. See I_PUSH in streamio(7I). tirdwr converts XTI/TLI above the transport provider into a pure read/write interface. With the module in place, the client calls close(2) and dup(2) to establish the transport endpoint as its standard input file, and uses /usr/bin/cat to process the input.

By pushing tirdwr onto the transport provider, XTI/TLI is changed. The semantics of read(2) and write(2) must be used, and message boundaries are not preserved. tirdwr can be popped from the transport provider to restore XTI/TLI semantics (see I_POP in streamio(7I).

Caution - Caution -

The tirdwr module can only be pushed onto a stream when the transport endpoint is in the data transfer phase. After the module is pushed, the user cannot call any XTI/TLI routines. If an XTI/TLI routine is invoked, tirdwr generates a fatal protocol error, EPROTO, on the stream, rendering it unusable. If you then pop the tirdwr module off the stream, the transport connection is aborted. See I_POP in streamio(7I).


Send data over the transport connection with write(2). tirdwr passes data through to the transport provider. If you send a zero-length data packet, which the mechanism allows, tirdwr discards the message. If the transport connection is aborted--for example, because the remote user aborts the connection using t_snddis(3NSL)--a hang-up condition is generated on the stream, further write(2) calls fail, and errno is set to ENXIO. You can still retrieve any available data after a hang-up.


Receive data that arrives at the transport connection with read(2). tirdwr, which passes data from the transport provider. Any other event or request passed to the user from the provider is processed by tirdwr as follows:


With tirdwr on a stream, you can send and receive data over a transport connection for the duration of the connection. Either user can terminate the connection by closing the file descriptor associated with the transport endpoint or by popping the tirdwr module off the stream. In either case, tirdwr does the following:

A process cannot initiate an orderly release after tirdwr is pushed onto a stream. tirdwr handles an orderly release if it is initiated by the user on the other side of a transport connection. If the client in this section is communicating with the server program in "Connection Mode Service", the server terminates the transfer of data with an orderly release request. The server then waits for the corresponding request from the client. At that point, the client exits and the transport endpoint is closed. When the file descriptor is closed, tirdwr initiates the orderly release request from the client's side of the connection. This generates the request that the server is blocked on.

Some protocols, like TCP, require this orderly release to ensure that the data is delivered intact.