Print this page
14249 pseudo-terminal nomenclature should reflect POSIX
Change-Id: Ib4a3cef899ff4c71b09cb0dc6878863c5e8357bc

*** 1,99 **** ! PTS(7D) Devices PTS(7D) NAME ! pts - STREAMS pseudo-tty slave driver DESCRIPTION ! The pseudo-tty subsystem simulates a terminal connection, where the ! master side represents the terminal and the slave represents the user ! process's special device end point. In order to use the pseudo-tty ! subsystem, a node for the master side driver /dev/ptmx and N nodes for ! the slave driver (N is determined at installation time) must be ! installed. The names of the slave devices are /dev/pts/M where M has ! the values 0 through N-1. When the master device is opened, the ! corresponding slave device is automatically locked out. No user may ! open that slave device until its permissions are adjusted and the ! device unlocked by calling functions grantpt(3C) and unlockpt(3C). The ! user can then invoke the open system call with the name that is ! returned by the ptsname(3C) function. See the example below. ! Only one open is allowed on a master device. Multiple opens are allowed ! on the slave device. After both the master and slave have been opened, ! the user has two file descriptors which are end points of a full duplex ! connection composed of two streams automatically connected at the ! master and slave drivers. The user may then push modules onto either ! side of the stream pair. Unless compiled in XPG4v2 mode (see below), ! the consumer needs to push the ptem(7M) and ldterm(7M) modules onto the ! slave side of the pseudo-terminal subsystem to get terminal semantics. ! The master and slave drivers pass all messages to their adjacent queues. Only the M_FLUSH needs some processing. Because the read queue ! of one side is connected to the write queue of the other, the FLUSHR ! flag is changed to the FLUSHW flag and vice versa. When the master ! device is closed an M_HANGUP message is sent to the slave device which ! will render the device unusable. The process on the slave side gets the ! errno EIO when attempting to write on that stream but it will be able ! to read any data remaining on the stream head read queue. When all the ! data has been read, read returns 0 indicating that the stream can no ! longer be used. On the last close of the slave device, a 0-length ! message is sent to the master device. When the application on the ! master side issues a read() or getmsg() and 0 is returned, the user of ! the master device decides whether to issue a close() that dismantles ! the pseudo-terminal subsystem. If the master device is not closed, the ! pseudo-tty subsystem will be available to another user to open the ! slave device. Since 0-length messages are used to indicate that the ! process on the slave side has closed and should be interpreted that way ! by the process on the master side, applications on the slave side ! should not write 0-length messages. Unless the application is compiled ! in XPG4v2 mode (see below) then any 0-length messages written on the ! slave side will be discarded by the ptem module. ! The standard STREAMS system calls can access the pseudo-tty devices. ! The slave devices support the O_NDELAY and O_NONBLOCK flags. XPG4v2 MODE ! XPG4v2 requires that open of a slave pseudo terminal device provides ! the process with an interface that is identical to the terminal ! interface (without having to explicitly push any modules to achieve ! this). It also requires that 0-length messages written on the slave ! side will be propagated to the master. ! Experience has shown, however, that most software does not expect slave ! pty devices to operate in this manner and therefore this ! XPG4v2-compliant behaviour is only enabled in XPG4v2/SUS (see ! standards(5)) mode. ! EXAMPLES ! int fdm fds; ! char *slavename; ! extern char *ptsname(); ! fdm = open("/dev/ptmx", O_RDWR); /* open master */ ! grantpt(fdm); /* change permission of slave */ ! unlockpt(fdm); /* unlock slave */ ! slavename = ptsname(fdm); /* get name of slave */ ! fds = open(slavename, O_RDWR); /* open slave */ ! ioctl(fds, I_PUSH, "ptem"); /* push ptem */ ! ioctl(fds, I_PUSH, "ldterm"); /* push ldterm*/ FILES ! /dev/ptmx ! master clone device ! /dev/pts/M ! slave devices (M = 0 -> N-1) SEE ALSO ! grantpt(3C), ptsname(3C), unlockpt(3C), ldterm(7M), ptm(7D), ptem(7M), ! standards(5) ! ! STREAMS Programming Guide ! ! February 29, 2020 PTS(7D) --- 1,151 ---- ! PTM(7D) Devices PTM(7D) NAME ! ptm, pts - STREAMS pseudo-terminal manager and subsidiary drivers + SYNOPSIS + /dev/ptmx + + /dev/pts/* + DESCRIPTION ! The pseudo-terminal subsystem simulates a terminal connection, where the ! manager side represents the terminal and the subsidiary represents the ! user process's special device end point. The manager device is set up as ! a cloned device where its major device number is the major for the clone ! device and its minor device number is the major for the ptm driver; see ! CLONE_DEV in ddi_create_minor_node(9F). + There are no nodes in the file system for manager devices. The manager + pseudo driver is opened using the open(2) system call with /dev/ptmx as + the device parameter. The clone open finds the next available minor + device for the ptm major device. ! A manager device is only available if it and its corresponding subsidiary ! device are not already open. Only one open is allowed on a manager ! device. Multiple opens are allowed on the subsidiary device. + When the manager device is opened, the corresponding subsidiary device is + automatically locked out. No user may open the subsidiary device until + its permissions are adjusted and the device is unlocked by calling the + functions grantpt(3C) and unlockpt(3C). The user can then invoke the + open(2) system call with the device name returned by the ptsname(3C) + function. ! After both the manager and subsidiary have been opened, the user has two ! file descriptors which are the end points of a full duplex connection ! composed of two streams which are automatically connected at the manager ! and subsidiary drivers. The user may then push modules onto either side ! of the stream pair. Unless compiled in XPG4v2 mode (see XPG4v2 MODE), ! the consumer needs to push the ptem(7M) and ldterm(7M) modules onto the ! subsidiary device to get terminal semantics. ! ! The manager and subsidiary drivers pass all messages to their adjacent queues. Only the M_FLUSH needs some processing. Because the read queue ! of one side is connected to the write queue of the other, the FLUSHR flag ! is changed to the FLUSHW flag and vice versa. + When the manager device is closed, an M_HANGUP message is sent to the + subsidiary device which will render the device unusable. The process on + the subsidiary side gets an EIO error when attempting to write on that + stream, but it will be able to read any data remaining on the stream head + read queue. When all the data has been read, read(2) returns 0 + indicating that the stream can no longer be used. ! On the last close of the subsidiary device, a 0-length message is sent to ! the manager device. When the application on the manager side issues a ! read(2) or getmsg(2) and 0 is returned, the user of the manager device ! decides whether to issue a close(2) that dismantles the entire pseudo- ! terminal. If the manager device is not closed, the pseudo-terminal will ! be available to another user to open the subsidiary device. + Since 0-length messages are used to indicate that the process on the + subsidiary side has closed, and should be interpreted that way by the + process on the manager side, applications on the subsidiary side should + not write 0-length messages. Unless the application is compiled in + XPG4v2 mode (see XPG4v2 MODE), then any 0-length messages written to the + subsidiary device will be discarded by the ptem(7M) module. + + If O_NONBLOCK or O_NDELAY is set on the manager side: + + o Read on the manager side returns -1 with errno set to EAGAIN if no + data is available + + o Write returns -1 with errno set to EAGAIN if there is internal flow + control + + Standard STREAMS system calls can access pseudo-terminal devices. The + subsidiary devices support the O_NDELAY and O_NONBLOCK flags. + XPG4v2 MODE ! XPG4v2 requires that subsidiary pseudo-terminal devices provide the ! process with an interface that is identical to the terminal interface, ! without needing to explicitly push any modules to achieve this. It also ! requires that 0-length messages written on the subsidiary device will be ! propagated to the manager device. ! Experience has shown that most software does not expect subsidiary ! pseudo-terminal devices to operate in this manner. This XPG4v2-compliant ! behaviour is only enabled in XPG4v2/SUS (see standards(5)) mode. ! IOCTLS ! The manager driver provides several ioctls to support the grantpt(3C), ! unlockpt(3C), and ptsname(3C) functions: ! ISPTM Determines whether the file descriptor is that of an open manager ! device. On success, it returns the value 0. + UNLKPT Unlocks the manager and subsidiary devices. It returns 0 on + success. On failure, errno is set to EINVAL indicating that the + manager device is not open. FILES ! /dev/ptmx Pseudo-terminal manager clone device. + /dev/pts/N Pseudo-terminal subsidiary devices, + where N is a non-negative integer. + Located via calls to ptsname(3C). ! EXAMPLES ! Example 1 Opening the manager and subsidiary device for a pseudo- ! terminal. + #include <stdlib.h> + #include <sys/types.h> + #include <sys/stat.h> + #include <unistd.h> + #include <stropts.h> + #include <fcntl.h> + #include <err.h> + ... + int fdm, fds; + char *subsidiaryname; + ... + /* + * NOTE: Portable applications should use posix_openpt(3C) here: + */ + if ((fdm = open("/dev/ptmx", O_RDWR | O_NOCTTY)) < 0) { + err(1, "open manager"); + } + if (grantpt(fdm) != 0 || unlockpt(fdm) != 0 || + (subsidiaryname = ptsname(fdm)) == NULL) { + close(fdm); + err(1, "locate subsidiary"); + } + if ((fds = open(subsidiaryname, O_RDWR | O_NOCTTY)) < 0) { + close(fdm); + err(1, "open subsidiary"); + } + if (ioctl(fds, I_PUSH, "ptem") != 0 || + ioctl(fds, I_PUSH, "ldterm") != 0) { + close(fds); + close(fdm); + err(1, "push modules"); + } SEE ALSO ! close(2), getmsg(2), open(2), read(2), grantpt(3C), posix_openpt(3C), ! ptsname(3C), unlockpt(3C), standards(5), ldterm(7M), pckt(7M), ptem(7M), ! ddi_create_minor_node(9F) ! illumos February 5, 2022 illumos