xref: /illumos-gate/usr/src/man/man4d/ptm.4d (revision b8052df9f609edb713f6828c9eecc3d7be19dfb3)
1'\" te
2.\"  Copyright (c) 1997, Sun Microsystems, Inc.
3.\"  All Rights Reserved
4.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License.
5.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  See the License for the specific language governing permissions and limitations under the License.
6.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
7.\" Copyright 2022 Oxide Computer Company
8.Dd February 5, 2022
9.Dt PTM 4D
10.Os
11.Sh NAME
12.Nm ptm ,
13.Nm pts
14.Nd STREAMS pseudo-terminal manager and subsidiary drivers
15.Sh SYNOPSIS
16.Pa /dev/ptmx
17.Pp
18.Pa /dev/pts/*
19.Sh DESCRIPTION
20The pseudo-terminal subsystem simulates a terminal connection, where the
21manager side represents the terminal and the subsidiary represents the user
22process's special device end point.
23The manager device is set up as a cloned device where its major device number
24is the major for the clone device and its minor device number is the major for
25the
26.Nm ptm
27driver; see
28.Dv CLONE_DEV
29in
30.Xr ddi_create_minor_node 9F .
31.Pp
32There are no nodes in the file system for manager devices.
33The manager pseudo driver is opened using the
34.Xr open 2
35system call with
36.Pa /dev/ptmx
37as the device parameter.
38The clone open finds the next available minor device for the
39.Nm ptm
40major device.
41.Pp
42A manager device is only available if it and its corresponding subsidiary
43device are not already open.
44Only one open is allowed on a manager device.
45Multiple opens are allowed on the subsidiary device.
46.Pp
47When the manager device is opened, the corresponding subsidiary device is
48automatically locked out.
49No user may open the subsidiary device until its permissions are adjusted and
50the device is unlocked by calling the functions
51.Xr grantpt 3C
52and
53.Xr unlockpt 3C .
54The user can then invoke the
55.Xr open 2
56system call with the device name returned by the
57.Xr ptsname 3C
58function.
59.Pp
60After both the manager and subsidiary have been opened, the user has two file
61descriptors which are the end points of a full duplex connection composed of
62two streams which are automatically connected at the manager and subsidiary
63drivers.
64The user may then push modules onto either side of the stream pair.
65Unless compiled in XPG4v2 mode
66.Po
67see
68.Sx "XPG4v2 MODE"
69.Pc ,
70the consumer needs to push the
71.Xr ptem 4M
72and
73.Xr ldterm 4M
74modules onto the subsidiary device to get terminal semantics.
75.Pp
76The manager and subsidiary drivers pass all messages to their adjacent queues.
77Only the
78.Dv M_FLUSH
79needs some processing.
80Because the read queue of one side is connected to the write queue of the
81other, the
82.Dv FLUSHR
83flag is changed to the
84.Dv FLUSHW
85flag and vice versa.
86.Pp
87When the manager device is closed, an
88.Dv M_HANGUP
89message is sent to the subsidiary device which will render the device unusable.
90The process on the subsidiary side gets an
91.Er EIO
92error when attempting to write on that stream, but it will be able to read
93any data remaining on the stream head read queue.
94When all the data has been read,
95.Xr read 2
96returns
97.Sy 0
98indicating that the stream can no longer be used.
99.Pp
100On the last close of the subsidiary device, a 0-length message is sent to the
101manager device.
102When the application on the manager side issues a
103.Xr read 2
104or
105.Xr getmsg 2
106and
107.Sy 0
108is returned, the user of the manager device decides whether to issue a
109.Xr close 2
110that dismantles the entire pseudo-terminal.
111If the manager device is not closed, the pseudo-terminal will be available to
112another user to open the subsidiary device.
113.Pp
114Since 0-length messages are used to indicate that the process on the
115subsidiary side has closed, and should be interpreted that way by the process
116on the manager side, applications on the subsidiary side should not write
1170-length messages.
118Unless the application is compiled in XPG4v2 mode
119.Po
120see
121.Sx "XPG4v2 MODE"
122.Pc ,
123then any 0-length messages written to the subsidiary device will be discarded
124by the
125.Xr ptem 4M
126module.
127.Pp
128If
129.Dv O_NONBLOCK
130or
131.Dv O_NDELAY
132is set on the manager side:
133.Bl -bullet
134.It
135Read on the manager side returns
136.Sy -1
137with
138.Va errno
139set to
140.Er EAGAIN
141if no data is available
142.It
143Write returns
144.Sy -1
145with
146.Va errno
147set to
148.Er EAGAIN
149if there is internal flow control
150.El
151.Pp
152Standard STREAMS system calls can access pseudo-terminal devices.
153The subsidiary devices support the
154.Dv O_NDELAY
155and
156.Dv O_NONBLOCK
157flags.
158.Sh XPG4v2 MODE
159.Em XPG4v2
160requires that subsidiary pseudo-terminal devices provide the process with an
161interface that is identical to the terminal interface, without needing to
162explicitly push any modules to achieve this.
163It also requires that 0-length messages written on the subsidiary device will
164be propagated to the manager device.
165.Pp
166Experience has shown that most software does not expect subsidiary
167pseudo-terminal devices to operate in this manner.
168This XPG4v2-compliant behaviour is only enabled in XPG4v2/SUS
169.Po
170see
171.Xr standards 7
172.Pc
173mode.
174.Sh IOCTLS
175The manager driver provides several ioctls to support the
176.Xr grantpt 3C ,
177.Xr unlockpt 3C ,
178and
179.Xr ptsname 3C
180functions:
181.Bl -tag -width Ds
182.It Dv ISPTM
183Determines whether the file descriptor is that of an open manager device.
184On success, it returns the value
185.Sy 0 .
186.It Dv UNLKPT
187Unlocks the manager and subsidiary devices.
188It returns
189.Sy 0
190on success.
191On failure,
192.Vt errno
193is set to
194.Vt EINVAL
195indicating that the manager device is not open.
196.El
197.Sh FILES
198.Bl -tag -width Pa
199.It Pa /dev/ptmx
200Pseudo-terminal manager clone device.
201.It Pa /dev/pts/N
202Pseudo-terminal subsidiary devices, where
203.Sy N
204is a non-negative integer.
205Located via calls to
206.Xr ptsname 3C .
207.El
208.Sh EXAMPLES
209.Sy Example 1
210Opening the manager and subsidiary device for a pseudo-terminal.
211.Bd -literal -offset Ds
212#include <stdlib.h>
213#include <sys/types.h>
214#include <sys/stat.h>
215#include <unistd.h>
216#include <stropts.h>
217#include <fcntl.h>
218#include <err.h>
219\&...
220int fdm, fds;
221char *subsidiaryname;
222\&...
223/*
224 * NOTE: Portable applications should use posix_openpt(3C) here:
225 */
226if ((fdm = open("/dev/ptmx", O_RDWR | O_NOCTTY)) < 0) {
227        err(1, "open manager");
228}
229if (grantpt(fdm) != 0 || unlockpt(fdm) != 0 ||
230    (subsidiaryname = ptsname(fdm)) == NULL) {
231        close(fdm);
232        err(1, "locate subsidiary");
233}
234if ((fds = open(subsidiaryname, O_RDWR | O_NOCTTY)) < 0) {
235        close(fdm);
236        err(1, "open subsidiary");
237}
238if (ioctl(fds, I_PUSH, "ptem") != 0 ||
239    ioctl(fds, I_PUSH, "ldterm") != 0) {
240        close(fds);
241        close(fdm);
242        err(1, "push modules");
243}
244.Ed
245.Sh SEE ALSO
246.Xr close 2 ,
247.Xr getmsg 2 ,
248.Xr open 2 ,
249.Xr read 2 ,
250.Xr grantpt 3C ,
251.Xr posix_openpt 3C ,
252.Xr ptsname 3C ,
253.Xr unlockpt 3C ,
254.Xr ldterm 4M ,
255.Xr pckt 4M ,
256.Xr ptem 4M ,
257.Xr standards 7 ,
258.Xr ddi_create_minor_node 9F
259