PTY(4)
NAME
pty − pseudo terminal driver
SYNOPSIS
pseudo-device pty
HP-UX COMPATIBILITY
Level: HP-UX/STANDARD
Origin: Berkeley 4.2
DESCRIPTION
The pty driver provides a communication path between an HP-UX application process and a supporting server process, and behaves much like a terminal/computer communication path. It is structured so that output from either process acts as input to the other, thus the term pseudoterminal. The slave-side of pty interacts with the application process, and its behavior is defined by termio(4). The master-side of pty interacts with the server process which controls the application process through pty as if pty were a hardware terminal interface.
The following ioctl requests, defined in <sys/ptyio.h>, apply only to master side of pty:
TIOCBREAK
Causes a break operation to be done on the slave side of the pty. This action is the same as if a user had hit the break key on a real terminal. Takes no parameters.
TIOCSIGSEND
Causes a signal to be sent on the slave side of the pty to the current tty process group of the slave side. The value of the parameter is taken to be the signal number to be sent. An EINVAL error will be returned and no signal sent if the specified signal number does not refer to a legal signal (see signal(2)). Note that this request allows the server process to send signals to processes that are not owned by the same user id.
TIOCSTOP
Stops data flowing from the slave side of the pty to the master side (e.g. like typing ^S). Takes no parameters.
TIOCSTART
Restarts output (stopped by TIOCSTOP or by typing ^S). Takes no parameters.
TIOCPKT
Enable/disable packet mode. Packet mode is enabled by specifying (by reference) a nonzero int parameter and disabled by specifying (by reference) a zero int parameter. When applied to the master side of a pseudo terminal, each subsequent read from the master side will return data written on the slave part of the pseudo terminal preceded by a zero byte (symbolically defined as TIOCPKT_DATA), or a single byte reflecting control status information. In the latter case, the byte is an inclusive-or of zero or more of the bits:
TIOCPKT_FLUSHREAD
whenever the read queue for the slave side is flushed.
TIOCPKT_FLUSHWRITE
whenever the write queue for the slave side is flushed.
TIOCPKT_STOP
whenever data flowing from the slave side of the pty to the master side is stopped by means of ^S, TIOCSTOP, or TCXONC.
TIOCPKT_START
whenever data flowing from the slave side of the pty to the master side is restarted.
TIOCPKT_DOSTOP
whenever the stop and start characters get set to ^S/^Q.
TIOCPKT_NOSTOP
whenever the stop and start characters get set to something other than ^S/^Q.
TIOCREMOTE
A mode for the master half of a pseudo terminal, independent of TIOCPKT. This mode causes input to the pseudo terminal to be flow controlled and not input edited (regardless of the terminal mode). Each write to the master side produces a record boundary for the process reading the slave side. In normal usage, a write of data is like the data typed as a line on the terminal; a write of 0 bytes is like typing an end-of-file character (the EOF character as defined in termio(4)). The data read by the slave side is identical to the data written on the master side. Data written on the slave side and read on the master side with TIOCREMOTE enabled is still subject to the normal termio(4) processing. TIOCREMOTE can be used when doing remote line editing in a window manager, or whenever flow controlled input is required. The request takes one int sized parameter, passed by value. When zero, it disables TIOCREMOTE; when one it enables TIOCREMOTE. TIOCREMOTE is only effective when TIOCTTY (explained below) is also enabled, and all data buffered in the pseudo terminal will be flushed when this request is made.
TIOCTTY
Enable or disable all termio(4) processing by pty. When disabled, all data is passed through the pty with no modification. Termio(4) processing (of input and output such as tab expansion) is enabled by specifying (by reference) a nonzero int parameter and disabled by specifying (by reference) a zero int parameter. Default is to be enabled. When TIOCTTY is disabled, the following pty modes are also inoperable: TIOCBREAK, TIOCSTOP, TIOCSTART, TIOCPKT, TIOCREMOTE, and TIOCMONITOR. Issuing a TIOCTTY ioctl request will also flush all data buffered in the pseudo terminal, and release any processes currently blocked waiting for data.
When TIOCTTY is enabled (the default case), all termio(4) ioctl requests are handled by the pty driver itself. When TIOCTTY is disabled, slave side termio(4) ioctl requests are either ignored completely or passed to the master side depending upon the state of TIOCTRAP below. Slave side non-termio(4) ioctl requests are not affected by the state of TIOCTTY. They are always ignored completely or passed to the master side depending upon the state of TIOCTRAP below.
Data being written through a pseudo terminal with TIOCTTY disabled will be handled in a manner similar to the way data flows through a pipe. A write request will block in the pty until all of its data has been written into the pty. A read request will block if there is no data available unless the O_NDELAY flag is set (see fcntl(2)). When data is available to be read, the read request will return whatever is available, and will not wait for the number of bytes requested to be satisfied. The number of bytes a pty can contain in its internal memory is implementation dependent, but will always be at least 256 bytes in each direction. For example, a write on the slave side of a pty of 1024 bytes might be read on the master side by four read requests returning 256 bytes each. The size of the chunks of data that are read is not guaranteed to be consistent, but no data will be lost.
Opening and closing of the master side acts as a modem connection/disconnection on a real terminal as far as the slave side is concerned. Having no server on the master side will cause opens on the slave side to hang until there is a server. (termio(4) description of O_NDELAY interaction with pty is also supported.) Opens to the master side are exclusive. Attempts to open an already open master side of a pty will return errno(2) error EBUSY. (Attempts to open a non-existent pty will return errno(2) ENXIO.) Closing the master side of a pty sends a SIGHUP hangup signal to the tty process group number of the corresponding slave side and flushes pending input and output.
Any termio(4) ioctl request can also be applied to the master side of the pty, unless TIOCTTY has been disabled.
IOCTL/OPEN/CLOSE TRAPPING
The capabilities that follow give additional flexibility and control for servers connected to the master side.
When trapping of ioctl/open/close is enabled, ioctl(2), open(2), and close(2) requests made to the slave side will notify the server on the master side of each request. The close request will only notify the server and continue to completion, while the open and ioctl requests will not complete until the master side has had a chance to handle them. The master side acknowledges completion via an ioctl to the master side. If the pty is not enabled to pass ioctl(2), open(2), and close(2) from the slave to the master, then they will be ignored (except for termio(4) related processing).
The following ioctl calls apply only to the master side of a pty and pertain to trapping open, close, and ioctl. They are also defined in <sys/ptyio.h>:
TIOCTRAP
Enable or disable trapping of ioctl, open, and close from the slave side. Trapping is enabled by specifying (by reference) a nonzero int parameter and disabled by specifying (by reference) a zero int parameter. Default is to be disabled. (termio(4) ioctl requests will not be trapped, unless TIOCTTY is also disabled or TIOCMONITOR is enabled.)
TIOCTRAPSTATUS
Find out if any ioctl/open/close traps are pending. The argument points to an int, that will be set to one if anything is pending and zero if nothing is pending. This ioctl request is used when the preferred method of a select(2) “exceptional condition” is not available.
TIOCREQGET
In response to a select(2) “exceptional condition” on the master side, this ioctl request will read the pending ioctl, open, or close information into memory pointed to by the argument in the form:
struct request_info {
int request;
int argget;
int argset;
short pgrp;
short pid;
int errno_error;
int return_value;
};
All elements of request_info refer to the slave side of the pty. Enumerating the elements:
request is the ioctl command received.
argget is the ioctl request to apply to master side to receive the trapped ioctl structure if there is one to receive, (a zero value means there is none). (When nonzero, argget is a TIOCARGGET request with the size field precomputed.)
argset is the ioctl request to apply to master side to send back the resulting ioctl structure if there is one to send back, (a zero value means there is none). (When nonzero, argset is a TIOCARGSET request with the size field precomputed.)
pgrp is the process group number of the process doing the operation.
pid is the process id of the process doing the operation.
errno_error is the errno(2) error code (initialized to zero) to be returned by ioctl on the slave side.
return_value (initialized to zero) is the success value to be returned by ioctl on the slave side when errno_error is not set.
For the case that the ioctl argument received on the slave side is not a pointer, its value is stored as four bytes that can be retrieved with an ioctl request to the master side equal to argget.
When an open or close is being passed, request will be set to TIOCOPEN or TIOCCLOSE, respectively. For TIOCOPEN and TIOCCLOSE, both argget and argset will be of zero because there is no ioctl structure. When TIOCTTY is enabled, the termio(4) definition of open/close will be executed first, before being passed to the master side. Note, while all opens are trapped, only the last close on a particular inode for a pty slave side is trapped by the pty.
If a TIOCREQGET is done before anything has been trapped, this master side ioctl will block until a slave side ioctl, open, or close is trapped.
TIOCREQSET
Done to complete the handshake started by a previous TIOCREQGET. The argument should point to the request_info structure as defined by the TIOCREQGET.
Before doing this ioctl, to complete the handshake, the server should set errno_error to an errno(2) error value to be passed back to the slave side. If there is no error, errno_error can be left alone because the pty will have initialized it to zero. Also, when there is no error, return_value should be set, if other than a zero result is desired. It should be noted that the ability to determine the return value and error code for a request to the slave side is only available for trapped ioctl requests. The server will not be able to set these values if the trapped request is an open or a close.
If the TIOCREQSET request is made and request in the passed request_info structure does not equal the trapped value, errno(2) EINVAL will be returned. (EINVAL is also returned if there is no trapped ioctl/open/close.)
If the trapped slave-side request has been interrupted by a signal between the time that the server has done the TIOCREQGET and the TIOCREQSET, an EINVAL error will be returned by the TIOCREQSET request.
TIOCMONITOR
Enable or disable read only trapping of termio ioctl requests when TIOCTTY is also enabled. (When TIOCTTY is disabled, TIOCMONITOR has no effect. Also TIOCMONITOR is independent of TIOCTRAP.) Trapping is enabled by specifying (by reference) a nonzero int parameter and disabled by specifying (by reference) a zero int parameter. Default is to be disabled.
This allows a server process attached to the master side of the pty to know when characteristics of the line discipline in the pty are changed by an application on the slave side. The mechanism for handshaking trapped termio(4) requests (when TIOCTTY is enabled) is the same as that for non-termio(4) ioctl requests; except that any changes or error conditions set by the server on the master side will have no effect. (It is recommended that termio(4) ioctl requests be used on the master side to interrogate the configured state of the line discipline in the pty. One reason for this is to compensate for the window of time before TIOCMONITOR is enabled, when termio(4) ioctls were not trapped.)
When using select(2) on the master side of a pty, the “exceptional condition” refers to an open, close, or ioctl pending on the slave side. Ready for reading or writing refers to a read, or write pending respectively, from the point of view of the master side.
Of the ioctls that are subject to being trapped, only one per pty may be handled at one time. This means that when an application does a non-termio(4) ioctl to the slave side, all other ioctls to the same pty slave side will be blocked until the first one is handshaked back by the master side. (Ioctls that are not trapped, such as termio(4) when TIOCTTY is enabled and TIOCMONITOR is disabled, will not be blocked.) This permits the implementation of indivisible operations by an ioctl call on the slave side that is passed to the server process.
In summary, handshaking of an ioctl/open/close on the master side is done using the following steps:
Slave Side open/close/ioctl Trapped.
This is indicated via a select(2) exceptional condition or via the TIOCTRAPSTATUS ioctl request.
TIOCREQGET ioctl request.
This is done to find out what slave open/close/ioctl is trapped.
argget ioctl request.
This optional ioctl is done if argget is nonzero and the server wants to do more than just reject the trapped slave ioctl.
argset ioctl request.
This optional ioctl is done if argset is nonzero and the server wants to pass back a modified ioctl structure. It is done after the trapped ioctl is processed via the server on the master side.
TIOCREQSET ioctl request.
This is done to complete the trapped slave open/close/ioctl. In case the trapped request is an ioctl, errno_error should be set appropriately. return_value should be set for trapped slave ioctls if errno_error is set to zero.
While a process is waiting in the slave side of the pty for the server to complete a handshake, it is susceptible to receiving signals. The following master side ioctl allows the server process to control how the pty will respond when a signal attempts to interrupt a trapped open or ioctl request.
TIOCSIGMODE
Sets the signal handling state of the pty to the mode specified as the argument. The mode can have three values, which are TIOCSIGBLOCK, TIOCSIGABORT, and TIOCSIGNORMAL.
TIOCSIGBLOCK
Causes some signals that are destined for the process whose open/ioctl is trapped to be postponed. The signals that are blocked are those which would otherwise cause the process to jump to an installed signal handler. Signals that are currently being ignored or would cause the slave-side process to be aborted will not be held off. When the server process completes the handshake by means of the TIOCREQSET ioctl request, the slave-side process will return to the calling program, and any pending signals will then be acted upon. Any signals that the user has blocked by means of sigblock(2) will continue to be blocked.
TIOCSIGABORT
Forces all signals that interrupt a trapped open/ioctl request to not be restartable. The server process will set this mode when it wants the interrupted requests to return to the calling program with an EINTR error.
TIOCSIGNORMAL
This is the default mode of the pty. If a signal interrupts a trapped open/ioctl request, the user’s signal handler routine has the option of specifying whether the request is to be restarted. If the request is to be restarted, it will be executed again from the begining, and the server will have to do another TIOCREQGET to start the handshake over again. If the user’s signal handler routine specifies that the interrupted request is not to be restarted, then the request will return to the calling program with EINTR upon completion of the signal handler. Note that it is not guaranteed that the restarted request will be the very next one to be trapped.
HARDWARE DEPENDENCIES
Series 200:
The largest ioctl argument passable between master and slave sides is currently limited to 128 bytes.
Series 500:
The largest ioctl argument passable between master and slave sides is currently limited to 128 bytes.
The TIOCREMOTE mode is not currently implemented.
FILES
/dev/ptym/pty[pqrstuvw]*master pseudo terminals
/dev/pty/tty[pqrstuvw]* slave pseudo terminals
DIAGNOSTICS
None.
BUGS
It is not possible for the slave side to indicate an end-of-fle condition to the master side.
When using TIOCREMOTE, a single write to the master side of greater than 256 bytes may result in multiple smaller records being read from the slave side instead of only one record.
SEE ALSO
termio(4), ioctl(2), select(2), signal(2).
Hewlett-Packard — last mod. May 11, 2021