.title A Pseudo-Terminal Device for VAX/VMS .no autosubtitle .p 0 .ap .s 20 .c;A Pseudo-Terminal Device for VAX/VMS .s .c;Draft Document .s 3 .c;Gary L. Grebus .s .c;Battelle Columbus Labs .s .c;Columbus, Ohio .s .c;20-February-1984 .page .layout 2,4 .number 1 .hl 1 Introduction This document describes an implementation of pseudo-terminals for VAX/VMS. A pseudo-terminal, often called a PTY, is a software device used for communication between two processes. It is a software, or pseudo-device; no hardware is involved. A PTY is similar to a mailbox in that it is used for inter-process communication. A PTY however, responds correctly to all QIO functions defined for a real terminal device. Thus, a PTY can be used with programs which expect to drive a terminal (such as a text editor) and which may issue QIO's that are undefined for mailboxes. Typical applications of a pseudo-terminal include hardcopy logging of terminal interaction, and remote terminal support for networks. .hl 1 VAX/VMS Pseudo-terminals PTY's for VAX/VMS are implemented via a device driver which works in conjunction with the standard VMS terminal class driver. Installation of this device driver creates a device with the name PTY0:. A new PTY is dynamically created when you attempt to assign a channel on PTY0:. This action in fact causes a pair of PTY devices to be created. The PTY's have consecutive unit numbers (e.g. PTY19: and PTY20:). The device with the higher unit number is called the terminal device. It supports the full set of VMS terminal driver functions. The device with the lower unit number is called the control device. It supports a restricted set of terminal functions. In typical use, the terminal device is assigned as the primary input/output device of a process running DCL or some application. The control device is assigned to a program which interacts with the user. Characters written as output on the control device appear as input typed on the terminal device. Characters written as output on the terminal device appear as input on the control device. .hl 1 Building and Installing the Driver The PTYDRIVER executable image can be rebuilt using the following commands: .S .lm +5 $ MACRO/LIST PTYDRIVER .BR $ LINK/MAP/FULL/NOTRACE - .BR #####PTYDRIVER+SYS$INPUT/OPTION+- #####SYS$SYSTEM:SYS.STB/SELECTIVE .BR #####BASE=0 .br #####_^Z .S .LM -5 To install an existing PTYDRIVER image, copy the PTYDRIVER.EXE file to SYS$SYSTEM and issue the following commands: .s .lm +5 $ RUN SYS$SYSTEM:SYSGEN .BR SYSGEN> CONNECT PTY0/NOADAPTER/DRIVER=PTYDRIVER .br SYSGEN> _^Z .lm -5 .s Installing the driver requires CMKRNL privilege. The driver has been tested and functions on VMS Versions 3.4 and 3.5. At minimum, the driver executable will need to be rebuilt for the next major release of VMS. Since undocumented driver interfaces are used, it is very likely that source code changes will also be required for compatability with future releases of VMS. .hl 1 Driver Features and Capabilities The PTY terminal device supports most of the features of standard VMS terminals devices. Except as described below, a PTY functions as described in the ^&VAX/VMS I/O User's Guide (Volume 1)\&, Section 9.2. Input data which would normally come from a terminal keyboard comes instead from the output of the opposite member of a PTY pair. Output data which would normally go to the terminal display appears instead as input on the opposite PTY device. The following differences exist between a PTY and a terminal: .list "o" .le A PTY is always a TYPEAHEAD terminal with HOSTSYNC and TTSYNC attributes. This insures that data transfers between the control and terminal device are always buffered and synchronized. For efficiency, PTY's are created as ALTYPEAHD devices to provide additional space for buffering. .le The terminal hang-up mailbox message is not currently supported. The unsolicited data and broadcast mailbox messages are supported. .le The PTY control device functions as a PASSALL terminal. Therefore, recognition of control characters such as CTRL/O, CTRL/U, CTRL/C, etc. is not supported. Recognition of selectable line terminators and escape sequences is supported. .le PTY devices always function in full-duplex mode. .le All functions and attributes related to modem control and signals are unsupported. .le All functions and attributes related to terminal speed and parity are unsupported. .le The device type, page width, page length and terminal characteristics of the PTY control device are permanently fixed. Any changes made to these attributes are instead made to the attributes of the PTY terminal device. .le Some attributes of the PTY terminal device are also permanently fixed to insure proper functioning of the driver. These are "hardware" related attributes such as HOSTSYNC, DMA, and HANGUP. They should not affect the logical behavior of the device. .le The temporary (IO$__SETMODE) and permanent (IO$__SETCHAR) characteristics of a PTY device are always identical. .end list .hl 1 Using a PTY .hl 2 Creating the device In order to use a PTY, you must first cause the creation of a PTY device pair. This is accomplished by using the $ASSIGN system service to request a channel on the device PTY0:. When a channel is requested on PTY0:, a pair of PTY devices are created. These devices have consecutive unit numbers. The channel returned by the system service is actually assigned on the lower or odd numbered member of the pair, the PTY control device. For example, the following code will create a PTY pair and obtain a channel on the PTY control device: .skip .LM +5 .literal PTY__TEMPLATE: .ASCID /PTY0:/ ; PTY template unit PTY__CONTROL__CHAN: .BLKW 1 ; Channel number on control . . . $ASSIGN__S - DEVNAM=PTY__TEMPLATE,- CHAN=PTY__CONTROL__CHAN ; Create and get channel BLBC R0,ERROR .END LITERAL .SKIP .lm -5 If terminal mailboxes are to be used with the PTY device, the LIB$ASN__WTH__MBX Run-Time Library procedure can also be used to create and assign the device. .hl 2 Obtaining device information After creating the PTY pair, you normally must obtain the unit numbers of the devices that were created, and possibly their attributes. This is most easily done using the $GETDVI system service. The $GETDVI service can be used to obtain characteristics for both the control and terminal devices. The characteristics of the control device can also be obtained by performing an IO$__SENSEMODE QIO operation using the channel obtained when creating the PTY. The following example shows how to obtain the unit number and device dependent (terminal) characteristics of the PTY control device: .skip .lm +5 .literal PTY__CONTROL__UNIT: .BLKL 1 ; Unit number for PTY control PTY__TERMINAL__UNIT: .BLKL 1 ; Unit number for PTY terminal PTY__CONTROL__CHAR: .BLKQ 1 ; Control device characteristics DVI__LIST: .WORD 4 .WORD DVI$__UNIT .ADDRESS PTY__CONTROL__UNIT .LONG 0 .WORD 4 .WORD DVI$__DEVDEPEND ; First longword .ADDRESS PTY__CONTROL__CHAR .LONG 0 .WORD 4 .WORD DVI$__DEVDEPEND2 ; Second longword .ADDRESS PTY__CONTROL__CHAR+4 .LONG 0,0 . . . $GETDVI__S - CHAN=PTY__CONTROL__CHAN,- ITMLST=DVI__LIST BLBC R0,ERROR ADDL3 #1,PTY__CONTROL__UNIT,- PTY__TERMINAL__UNIT ; Compute terminal unit nr. .end literal .skip .lm -5 Once the unit number of the terminal device has been computed, it can be used to form the device name of the terminal device. This name can then be supplied to the $GETDVI service to obtain the attributes of the terminal device. The device attributes of a PTY are the same as those of a normal terminal. This includes the terminal type, page width and length, and those characteristics defined in Tables 9-6 and 9-7 of the ^&VAX/VMS I/O User's Guide (Volume 1)\&. However, the PTY device driver restricts the values of certain attributes. The attributes of the control device are permanently fixed as follows: .s .lm +5 Terminal type = UNKNOWN .br Page width = 80 .br Page length = 0 .br Characteristics = HOSTSYNC, LOWER, MECHFORM, MECHTAB, .BR ##################TTSYNC, NOBRDCST, EIGHTBIT, PASSALL, .BR ##################ALTYPEAHD, HANGUP, NOECHO, SCOPE .SKIP .LM -5 If you attempt to change the attributes of the control device, the fixed attributes are maintained, and the corresponding changes are made to the attributes of the PTY terminal device. The attributes of the PTY terminal device can assume any values legal for a normal terminal, except for the setting of a few characteristics bits. The fixed characteristics are: HOSTSYNC, TTSYNC, NOMODEM, NOREADSYNC, NOHALFDUP HANGUP, ALTYPEAHD, NODMA, NOAUTOBAUD, and NOSETSPEED. The default setting of all of the PTY terminal attributes is take from the values specified in the SYSGEN TTY parameters. .hl 2 Performing application dependent processing Once the PTY devices have been created and the unit numbers obtained, you can begin to use the PTY devices in your application. The device name of the PTY terminal device must normally be passed to the other process which will communicate through the PTY's. The other process would then assign a channel on the PTY terminal device it was given, and begin to communicate via QIO reads and writes. Write operations on either device will complete immediately unless the partner devices typeahead buffer is full. In this case, the write will not complete until the partner process reads some data to empty the buffer. Read operations will complete immediately if sufficient data is available in the typeahead buffer. Otherwise, they will not complete until the required data is written by the partner process. Read operations with the IO$M__TIMED modifier can be used to limit the time a read can stall and to obtain any incomplete records in the typeahead buffer. The attributes of the PTY control device are set to make the device as transparent as possible. Simple IO$__READVBLK and IO$__WRITEVBLK operations are normally sufficient to pass data to the partner process. Note that the default attributes of the PTY terminal device include the ECHO characteristic. This means that the output from the PTY terminal device includes both its input (as echoed by the application) and any output which the application generates. .hl 2 Deassigning the device A both devices of a PTY device pair will continue to exist as long as there is a channel assigned on the PTY control device. When the last channel is deassigned from the control device, the control device will be destroyed. If the terminal device has no channels assigned, it will be destroyed at the same time. However, if the terminal device has a channel, it will continue to exist even after the control device has vanished. In this situation, any write operations on the PTY terminal device will be discarded, and a read operations will wait indefinitely. When the last channel is deassigned from the PTY terminal device, the device will also disappear. To deassign and destroy a PTY device, use the $DASSGN system service, as shown in the following example: .lm +5 .skip .literal $DASSGN__S - CHAN=PTY__CONTROL__CHAN BLBC R0,ERROR .end literal .skip .lm -5 .hl 2 Quotas and privileges required The use of resources on VAX/VMS is controlled by quotas and privileges. The process which creates a PTY device pair requires the NETMBX privilege. In addition, the creator must have sufficient BYTLM quota for the creation of the two PTY Unit Control Blocks. The BYTLM required is equal to the value of the SYSGEN parameter LRPSIZE plus 32, which is normally 672 bytes. These two requirements are in addition to the FILLM, BYTLM, and BIOLM quotas which are needed for the QIO functions to be performed. The quota needed for QIO operations is the same as is needed for similar operations on a normal terminal device. .hl 1 Device Function Codes PTY devices support the same basic terminal I/O functions as normal VMS terminals. Except as described below, device function codes, modifiers, and parameters are the same as described in the ^&VAX/VMS I/O User's Guide (Volume 1)\&, Section 9.4. .hl 2 Read All terminal read functions and modifiers are supported. .hl 2 WRITE All terminal write functions and modifiers are supported. .hl 2 Set mode The set mode QIO function behaves differently when applied to the PTY control and terminal devices. Set mode on a PTY terminal device functions the same way as on a normal terminal device, except for certain attributes which cannot be changed (see Section 5.2 of this document). A valid set mode operation on a PTY control device will always complete successfully, but will never change the control device attributes. Instead, the attributes supplied in the set mode will applied to the corresponding PTY terminal device. This allows a program using the control device to initialize or alter the terminal device attributes. .note ** WARNING ** There is an unresolved problem with the use of the IO$__SETMODE QIO function. Do not issue a set mode request which CHANGES the value of the TT2$M__MODHANGUP or TT2$M__SETSPEED device characteristics. Changing these attributes requires logical or physical I/O privilege. If you do not have sufficient privilege, the set mode operation will fail, and leave the PTY attributes in a state which will cause the PTY to hang, unable to complete I/O requests. .end note The following additional restrictions exist on the use of the IO$__SETMODE function: .list "o" .le The QIO parameter P3 (speed specifier) is undefined. .le The QIO parameter P5 (parity flags) is undefined. .le The IO$M__CTRLCAST IO$M__CTRLYAST, IO$M__OUTBAND, and IO$M__INCLUDE function modifiers are undefined on the PTY control device. .le The IO$M__SET__MODEM, IO$M__HANGUP, IO$M__LOOPM, IO$M__UNLOOPM and IO$M__MAINT function modifiers. are undefined. .le The speed and parity fields of the IOSB are undefined. .end list .hl 2 Sense Mode The following restrictions exist on the use of the IO$__SENSEMODE function: .list .le The speed and parity fields of the IOSB are undefined. .le The IO$M__RD__MODEM qualifier is undefined. .end list .hl 2 Set and Sense characteristics Since PTY's are dynamic devices, the concept of permanent characteristics is not meaningful. The IO$__SENSECHAR function will return the same attributes returned by IO$__SENSEMODE. The IO$__SETCHAR function is undefined. .hl 1 Implementation The VAX/VMS PTY driver (PTYDRIVER) is implemented as a port driver to the VMS terminal class driver (TTDRIVER). A port driver is a special driver which handles the device dependent details for a more generalized class driver. Other terminal port drivers include DZDRIVER for DZ-11 hardware and YCDRIVER for DMF-32's. The port driver provides a specific set of routines for writing characters, handling interrupts, performing synchronization, etc. The class driver performs all aspects of the QIO interface, data buffering, and data interpretation. Thus a PTY can exactly mimic a VMS terminal while transferring characters between two processes. The device PTY0: is defined as a template device. This means that when a channel is assigned to PTY0:, a new device is created. This creation, and later destruction is handled by the same routines VMS uses to create and destroy mailbox and network devices. PTYDRIVER performs some special setting of UCB fields to insure that a PTY device appears as either a terminal or a mailbox at the appropriate times. The UCB specified for PTY0: is twice as large as that of a terminal device. The PTYDRIVER unit initialization routine takes care of converting the created single PTY device into the PTY pair. This is done by splitting the allocated UCB into two separate UCB's and adjusting various other fields in the I/O database. The two devices then communicate at STARTIO level. A transfer is started by output on one device of the pair. The appropriate class driver routines are called to return the characters received or to obtain additional characters to transmit. PTYDRIVER also provides a routine which controls the characteristics of the device. Both the control and terminal devices are forced to have the TTSYNC and HOSTSYNC characteristics. This forces the terminal class driver to generate and accept flow control and prevents the typeahead buffers of either device from overflowing. The devices also have the ALTYPAHEAD characteristic to increase the size of the buffers. This is intended as a performance enhancement and may not be strictly necessary. The devices are also forced to have the HANGUP characteristic so that port driver is called during device shutdown. This enables PTYDRIVER to perform necessary cleanup activities, including merging and causing deallocation of the PTY UCB's. Finally, the characteristics of the control device are set to prevent the interpretation and alteration of data (PASSALL, EIGHTBIT, etc.)