1*bbf21555SRichard Lowe'\" te 2*bbf21555SRichard Lowe.\" Copyright (c) 1997, Sun Microsystems, Inc. 3*bbf21555SRichard Lowe.\" All Rights Reserved 4*bbf21555SRichard Lowe.\" 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*bbf21555SRichard Lowe.\" 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*bbf21555SRichard Lowe.\" 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*bbf21555SRichard Lowe.\" Copyright 2022 Oxide Computer Company 8*bbf21555SRichard Lowe.Dd February 5, 2022 9*bbf21555SRichard Lowe.Dt PTM 4D 10*bbf21555SRichard Lowe.Os 11*bbf21555SRichard Lowe.Sh NAME 12*bbf21555SRichard Lowe.Nm ptm , 13*bbf21555SRichard Lowe.Nm pts 14*bbf21555SRichard Lowe.Nd STREAMS pseudo-terminal manager and subsidiary drivers 15*bbf21555SRichard Lowe.Sh SYNOPSIS 16*bbf21555SRichard Lowe.Pa /dev/ptmx 17*bbf21555SRichard Lowe.Pp 18*bbf21555SRichard Lowe.Pa /dev/pts/* 19*bbf21555SRichard Lowe.Sh DESCRIPTION 20*bbf21555SRichard LoweThe pseudo-terminal subsystem simulates a terminal connection, where the 21*bbf21555SRichard Lowemanager side represents the terminal and the subsidiary represents the user 22*bbf21555SRichard Loweprocess's special device end point. 23*bbf21555SRichard LoweThe manager device is set up as a cloned device where its major device number 24*bbf21555SRichard Loweis the major for the clone device and its minor device number is the major for 25*bbf21555SRichard Lowethe 26*bbf21555SRichard Lowe.Nm ptm 27*bbf21555SRichard Lowedriver; see 28*bbf21555SRichard Lowe.Dv CLONE_DEV 29*bbf21555SRichard Lowein 30*bbf21555SRichard Lowe.Xr ddi_create_minor_node 9F . 31*bbf21555SRichard Lowe.Pp 32*bbf21555SRichard LoweThere are no nodes in the file system for manager devices. 33*bbf21555SRichard LoweThe manager pseudo driver is opened using the 34*bbf21555SRichard Lowe.Xr open 2 35*bbf21555SRichard Lowesystem call with 36*bbf21555SRichard Lowe.Pa /dev/ptmx 37*bbf21555SRichard Loweas the device parameter. 38*bbf21555SRichard LoweThe clone open finds the next available minor device for the 39*bbf21555SRichard Lowe.Nm ptm 40*bbf21555SRichard Lowemajor device. 41*bbf21555SRichard Lowe.Pp 42*bbf21555SRichard LoweA manager device is only available if it and its corresponding subsidiary 43*bbf21555SRichard Lowedevice are not already open. 44*bbf21555SRichard LoweOnly one open is allowed on a manager device. 45*bbf21555SRichard LoweMultiple opens are allowed on the subsidiary device. 46*bbf21555SRichard Lowe.Pp 47*bbf21555SRichard LoweWhen the manager device is opened, the corresponding subsidiary device is 48*bbf21555SRichard Loweautomatically locked out. 49*bbf21555SRichard LoweNo user may open the subsidiary device until its permissions are adjusted and 50*bbf21555SRichard Lowethe device is unlocked by calling the functions 51*bbf21555SRichard Lowe.Xr grantpt 3C 52*bbf21555SRichard Loweand 53*bbf21555SRichard Lowe.Xr unlockpt 3C . 54*bbf21555SRichard LoweThe user can then invoke the 55*bbf21555SRichard Lowe.Xr open 2 56*bbf21555SRichard Lowesystem call with the device name returned by the 57*bbf21555SRichard Lowe.Xr ptsname 3C 58*bbf21555SRichard Lowefunction. 59*bbf21555SRichard Lowe.Pp 60*bbf21555SRichard LoweAfter both the manager and subsidiary have been opened, the user has two file 61*bbf21555SRichard Lowedescriptors which are the end points of a full duplex connection composed of 62*bbf21555SRichard Lowetwo streams which are automatically connected at the manager and subsidiary 63*bbf21555SRichard Lowedrivers. 64*bbf21555SRichard LoweThe user may then push modules onto either side of the stream pair. 65*bbf21555SRichard LoweUnless compiled in XPG4v2 mode 66*bbf21555SRichard Lowe.Po 67*bbf21555SRichard Lowesee 68*bbf21555SRichard Lowe.Sx "XPG4v2 MODE" 69*bbf21555SRichard Lowe.Pc , 70*bbf21555SRichard Lowethe consumer needs to push the 71*bbf21555SRichard Lowe.Xr ptem 4M 72*bbf21555SRichard Loweand 73*bbf21555SRichard Lowe.Xr ldterm 4M 74*bbf21555SRichard Lowemodules onto the subsidiary device to get terminal semantics. 75*bbf21555SRichard Lowe.Pp 76*bbf21555SRichard LoweThe manager and subsidiary drivers pass all messages to their adjacent queues. 77*bbf21555SRichard LoweOnly the 78*bbf21555SRichard Lowe.Dv M_FLUSH 79*bbf21555SRichard Loweneeds some processing. 80*bbf21555SRichard LoweBecause the read queue of one side is connected to the write queue of the 81*bbf21555SRichard Loweother, the 82*bbf21555SRichard Lowe.Dv FLUSHR 83*bbf21555SRichard Loweflag is changed to the 84*bbf21555SRichard Lowe.Dv FLUSHW 85*bbf21555SRichard Loweflag and vice versa. 86*bbf21555SRichard Lowe.Pp 87*bbf21555SRichard LoweWhen the manager device is closed, an 88*bbf21555SRichard Lowe.Dv M_HANGUP 89*bbf21555SRichard Lowemessage is sent to the subsidiary device which will render the device unusable. 90*bbf21555SRichard LoweThe process on the subsidiary side gets an 91*bbf21555SRichard Lowe.Er EIO 92*bbf21555SRichard Loweerror when attempting to write on that stream, but it will be able to read 93*bbf21555SRichard Loweany data remaining on the stream head read queue. 94*bbf21555SRichard LoweWhen all the data has been read, 95*bbf21555SRichard Lowe.Xr read 2 96*bbf21555SRichard Lowereturns 97*bbf21555SRichard Lowe.Sy 0 98*bbf21555SRichard Loweindicating that the stream can no longer be used. 99*bbf21555SRichard Lowe.Pp 100*bbf21555SRichard LoweOn the last close of the subsidiary device, a 0-length message is sent to the 101*bbf21555SRichard Lowemanager device. 102*bbf21555SRichard LoweWhen the application on the manager side issues a 103*bbf21555SRichard Lowe.Xr read 2 104*bbf21555SRichard Loweor 105*bbf21555SRichard Lowe.Xr getmsg 2 106*bbf21555SRichard Loweand 107*bbf21555SRichard Lowe.Sy 0 108*bbf21555SRichard Loweis returned, the user of the manager device decides whether to issue a 109*bbf21555SRichard Lowe.Xr close 2 110*bbf21555SRichard Lowethat dismantles the entire pseudo-terminal. 111*bbf21555SRichard LoweIf the manager device is not closed, the pseudo-terminal will be available to 112*bbf21555SRichard Loweanother user to open the subsidiary device. 113*bbf21555SRichard Lowe.Pp 114*bbf21555SRichard LoweSince 0-length messages are used to indicate that the process on the 115*bbf21555SRichard Lowesubsidiary side has closed, and should be interpreted that way by the process 116*bbf21555SRichard Loweon the manager side, applications on the subsidiary side should not write 117*bbf21555SRichard Lowe0-length messages. 118*bbf21555SRichard LoweUnless the application is compiled in XPG4v2 mode 119*bbf21555SRichard Lowe.Po 120*bbf21555SRichard Lowesee 121*bbf21555SRichard Lowe.Sx "XPG4v2 MODE" 122*bbf21555SRichard Lowe.Pc , 123*bbf21555SRichard Lowethen any 0-length messages written to the subsidiary device will be discarded 124*bbf21555SRichard Loweby the 125*bbf21555SRichard Lowe.Xr ptem 4M 126*bbf21555SRichard Lowemodule. 127*bbf21555SRichard Lowe.Pp 128*bbf21555SRichard LoweIf 129*bbf21555SRichard Lowe.Dv O_NONBLOCK 130*bbf21555SRichard Loweor 131*bbf21555SRichard Lowe.Dv O_NDELAY 132*bbf21555SRichard Loweis set on the manager side: 133*bbf21555SRichard Lowe.Bl -bullet 134*bbf21555SRichard Lowe.It 135*bbf21555SRichard LoweRead on the manager side returns 136*bbf21555SRichard Lowe.Sy -1 137*bbf21555SRichard Lowewith 138*bbf21555SRichard Lowe.Va errno 139*bbf21555SRichard Loweset to 140*bbf21555SRichard Lowe.Er EAGAIN 141*bbf21555SRichard Loweif no data is available 142*bbf21555SRichard Lowe.It 143*bbf21555SRichard LoweWrite returns 144*bbf21555SRichard Lowe.Sy -1 145*bbf21555SRichard Lowewith 146*bbf21555SRichard Lowe.Va errno 147*bbf21555SRichard Loweset to 148*bbf21555SRichard Lowe.Er EAGAIN 149*bbf21555SRichard Loweif there is internal flow control 150*bbf21555SRichard Lowe.El 151*bbf21555SRichard Lowe.Pp 152*bbf21555SRichard LoweStandard STREAMS system calls can access pseudo-terminal devices. 153*bbf21555SRichard LoweThe subsidiary devices support the 154*bbf21555SRichard Lowe.Dv O_NDELAY 155*bbf21555SRichard Loweand 156*bbf21555SRichard Lowe.Dv O_NONBLOCK 157*bbf21555SRichard Loweflags. 158*bbf21555SRichard Lowe.Sh XPG4v2 MODE 159*bbf21555SRichard Lowe.Em XPG4v2 160*bbf21555SRichard Lowerequires that subsidiary pseudo-terminal devices provide the process with an 161*bbf21555SRichard Loweinterface that is identical to the terminal interface, without needing to 162*bbf21555SRichard Loweexplicitly push any modules to achieve this. 163*bbf21555SRichard LoweIt also requires that 0-length messages written on the subsidiary device will 164*bbf21555SRichard Lowebe propagated to the manager device. 165*bbf21555SRichard Lowe.Pp 166*bbf21555SRichard LoweExperience has shown that most software does not expect subsidiary 167*bbf21555SRichard Lowepseudo-terminal devices to operate in this manner. 168*bbf21555SRichard LoweThis XPG4v2-compliant behaviour is only enabled in XPG4v2/SUS 169*bbf21555SRichard Lowe.Po 170*bbf21555SRichard Lowesee 171*bbf21555SRichard Lowe.Xr standards 7 172*bbf21555SRichard Lowe.Pc 173*bbf21555SRichard Lowemode. 174*bbf21555SRichard Lowe.Sh IOCTLS 175*bbf21555SRichard LoweThe manager driver provides several ioctls to support the 176*bbf21555SRichard Lowe.Xr grantpt 3C , 177*bbf21555SRichard Lowe.Xr unlockpt 3C , 178*bbf21555SRichard Loweand 179*bbf21555SRichard Lowe.Xr ptsname 3C 180*bbf21555SRichard Lowefunctions: 181*bbf21555SRichard Lowe.Bl -tag -width Ds 182*bbf21555SRichard Lowe.It Dv ISPTM 183*bbf21555SRichard LoweDetermines whether the file descriptor is that of an open manager device. 184*bbf21555SRichard LoweOn success, it returns the value 185*bbf21555SRichard Lowe.Sy 0 . 186*bbf21555SRichard Lowe.It Dv UNLKPT 187*bbf21555SRichard LoweUnlocks the manager and subsidiary devices. 188*bbf21555SRichard LoweIt returns 189*bbf21555SRichard Lowe.Sy 0 190*bbf21555SRichard Loweon success. 191*bbf21555SRichard LoweOn failure, 192*bbf21555SRichard Lowe.Vt errno 193*bbf21555SRichard Loweis set to 194*bbf21555SRichard Lowe.Vt EINVAL 195*bbf21555SRichard Loweindicating that the manager device is not open. 196*bbf21555SRichard Lowe.El 197*bbf21555SRichard Lowe.Sh FILES 198*bbf21555SRichard Lowe.Bl -tag -width Pa 199*bbf21555SRichard Lowe.It Pa /dev/ptmx 200*bbf21555SRichard LowePseudo-terminal manager clone device. 201*bbf21555SRichard Lowe.It Pa /dev/pts/N 202*bbf21555SRichard LowePseudo-terminal subsidiary devices, where 203*bbf21555SRichard Lowe.Sy N 204*bbf21555SRichard Loweis a non-negative integer. 205*bbf21555SRichard LoweLocated via calls to 206*bbf21555SRichard Lowe.Xr ptsname 3C . 207*bbf21555SRichard Lowe.El 208*bbf21555SRichard Lowe.Sh EXAMPLES 209*bbf21555SRichard Lowe.Sy Example 1 210*bbf21555SRichard LoweOpening the manager and subsidiary device for a pseudo-terminal. 211*bbf21555SRichard Lowe.Bd -literal -offset Ds 212*bbf21555SRichard Lowe#include <stdlib.h> 213*bbf21555SRichard Lowe#include <sys/types.h> 214*bbf21555SRichard Lowe#include <sys/stat.h> 215*bbf21555SRichard Lowe#include <unistd.h> 216*bbf21555SRichard Lowe#include <stropts.h> 217*bbf21555SRichard Lowe#include <fcntl.h> 218*bbf21555SRichard Lowe#include <err.h> 219*bbf21555SRichard Lowe\&... 220*bbf21555SRichard Loweint fdm, fds; 221*bbf21555SRichard Lowechar *subsidiaryname; 222*bbf21555SRichard Lowe\&... 223*bbf21555SRichard Lowe/* 224*bbf21555SRichard Lowe * NOTE: Portable applications should use posix_openpt(3C) here: 225*bbf21555SRichard Lowe */ 226*bbf21555SRichard Loweif ((fdm = open("/dev/ptmx", O_RDWR | O_NOCTTY)) < 0) { 227*bbf21555SRichard Lowe err(1, "open manager"); 228*bbf21555SRichard Lowe} 229*bbf21555SRichard Loweif (grantpt(fdm) != 0 || unlockpt(fdm) != 0 || 230*bbf21555SRichard Lowe (subsidiaryname = ptsname(fdm)) == NULL) { 231*bbf21555SRichard Lowe close(fdm); 232*bbf21555SRichard Lowe err(1, "locate subsidiary"); 233*bbf21555SRichard Lowe} 234*bbf21555SRichard Loweif ((fds = open(subsidiaryname, O_RDWR | O_NOCTTY)) < 0) { 235*bbf21555SRichard Lowe close(fdm); 236*bbf21555SRichard Lowe err(1, "open subsidiary"); 237*bbf21555SRichard Lowe} 238*bbf21555SRichard Loweif (ioctl(fds, I_PUSH, "ptem") != 0 || 239*bbf21555SRichard Lowe ioctl(fds, I_PUSH, "ldterm") != 0) { 240*bbf21555SRichard Lowe close(fds); 241*bbf21555SRichard Lowe close(fdm); 242*bbf21555SRichard Lowe err(1, "push modules"); 243*bbf21555SRichard Lowe} 244*bbf21555SRichard Lowe.Ed 245*bbf21555SRichard Lowe.Sh SEE ALSO 246*bbf21555SRichard Lowe.Xr close 2 , 247*bbf21555SRichard Lowe.Xr getmsg 2 , 248*bbf21555SRichard Lowe.Xr open 2 , 249*bbf21555SRichard Lowe.Xr read 2 , 250*bbf21555SRichard Lowe.Xr grantpt 3C , 251*bbf21555SRichard Lowe.Xr posix_openpt 3C , 252*bbf21555SRichard Lowe.Xr ptsname 3C , 253*bbf21555SRichard Lowe.Xr unlockpt 3C , 254*bbf21555SRichard Lowe.Xr ldterm 4M , 255*bbf21555SRichard Lowe.Xr pckt 4M , 256*bbf21555SRichard Lowe.Xr ptem 4M , 257*bbf21555SRichard Lowe.Xr standards 7 , 258*bbf21555SRichard Lowe.Xr ddi_create_minor_node 9F 259