Go to main content

Oracle® Solaris 11.4 Programming Interfaces Guide

Exit Print View

Updated: November 2020

XTI/TLI Read/Write Interface

To process the data as it arrives over the connection, a user can establish a transport connection using exec() on an existing program such as /usr/bin/cat. Existing programs use read() and write(). XTI/TLI does not directly support a read/write interface to a transport provider, but one may be provided by using the tirdwr module. For more information, see the exec(2), read(2), and write(2) man pages. The interface enables you to issue read() and write() calls over a transport connection in the data transfer phase. This section describes the read/write interface with the XTI/TLI connection mode service. This interface is not available with the connectionless mode service.

Example 40  Using the XTI/TLI 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 the tirdwr module onto the stream associated with the transport endpoint. For more information about I_PUSH, see the streamio(4I) man page. The tirdwr module converts XTI/TLI above the transport provider into a read/write interface. Once the the tirdwr module is pushed, the client calls close() and dup() to establish the transport endpoint as its standard input file, and uses /usr/bin/cat to process the input. For more information, see the close(2) and dup(2).

Pushing the tirdwr module onto the transport provider forces XTI/TLI to use read() and write() semantics. XTI/TLI does not preserve message boundaries when using read() and write() semantics. Pop tirdwr from the transport provider to restore the XTI/TLI semantics. For more information about I_POP, see the streamio(4I) man page.

Caution  -  Push the tirdwr module onto a stream only when the transport endpoint is in the data transfer phase. After pushing the module, the user cannot call any XTI/TLI routines. If the user invokes an XTI/TLI routine, 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 aborts.

Write Data

After you send data over the transport connection with write(), tirdwr passes data through the transport provider. If you send a zero-length data packet, tirdwr discards the message. If the transport connection is aborted, a hang-up condition is generated on the stream and the write() calls fail, and errno is set to ENXIO. This problem might occur when the remote user aborts the connection using t_snddis(). You can still retrieve any available data after a hang-up. For more information, see the write(2) an t_snddis(3C) man pages.

Read Data

Receive data arrives at the transport connection with read(). The tirdwr module passes data from the transport provider. The tirdwr module processes any other event or request passed to the user from the provider as follows:

  • read() cannot identify expedited data to the user. If read() receives an expedited data request, tirdwr generates a fatal protocol error, EPROTO, on the stream. The error causes further system calls to fail. Do not use read() to receive expedited data.

  • tirdwr discards an abortive disconnect request and generates a hang-up condition on the stream. Subsequent read() calls retrieve any remaining data, then return zero for all further calls, indicating end of file.

  • tirdwr discards an orderly release request and delivers a zero-length message to the user. As described in the read() man page, this notifies the user of end of file by returning 0.

  • If read() receives any other XTI/TLI request, tirdwr generates a fatal protocol error, EPROTO, on the stream. This causes further system calls to fail. If a user pushes tirdwr onto a stream after establishing the connection, tirdwr generates no request. For more information, see the read(2) man page.

Close Connection

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:

  • If tirdwr receives an orderly release request, it passes the request to the transport provider to complete the orderly release of the connection. The remote user who initiated the orderly release procedure receives the expected request when data transfer completes.

  • If tirdwr receives a disconnect request, it takes no special action.

  • If tirdwr receives neither an orderly release nor a disconnect request, it passes a disconnect request to the transport provider to abort the connection.

  • If an error occurs on the stream and tirdwr does not receive a disconnect request, it passes a disconnect request to the transport provider.

A process cannot initiate an orderly release after pushing tirdwr onto a stream. tirdwr handles an orderly release if the user on the other side of a transport connection initiates the release. If the client in this section is communicating with a server program, 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 closes the transport endpoint. After closing the file descriptor, tirdwr initiates the orderly release request from the client's side of the connection. This release generates the request on which the server blocks.

Some protocols, like TCP, require this orderly release to ensure intact delivery of the data.