From:	CSBVAX::MRGATE!info-vax-RELAY@KL.SRI.COM@SMTP  4-JAN-1978 10:37
To:	ARISIA::EVERHART
Subj:	VMS pseudo-terminal drivers 1/5


Received: from BUSTER.NRC.COM by KL.SRI.COM with TCP; Tue, 21 Jun 88 16:37:43 PDT
Date: Tue, 21 Jun 88 16:32 PDT
From: Kevin Carosso <KVC@BUSTER.NRC.COM>
Subject: VMS pseudo-terminal drivers 1/5
To: info-vax@kl.sri.com, Dale.Moore@PS1.CS.CMU.EDU, asbed@oberon.usc.edu,
 dean%engvax.scg.hac.com@oberon.usc.edu, kvc@ymir.BITNET
X-VMS-To: @zz

....................... Cut between dotted lines and save. .....................
$!.............................................................................
$! VAX/VMS archive file created by VMS_SHARE V06.00 26-May-1988.
$!
$! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from
$! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au).
$!
$! To unpack, simply save, concatinate all parts into one file and
$! execute (@) that file.
$!
$! This archive was created by user KVC
$! on 14-OCT-1864 22:00:33.11.
$!
$! ATTENTION: To keep each article below 62 blocks (31744 bytes), this
$!            program has been transmitted in 5 parts.  You should
$!            concatenate ALL parts to ONE file and execute (@) that file.
$!
$! It contains the following 9 files:
$!        000_README.TXT
$!        BUILD.COM
$!        DRIVER.OPT
$!        NOTES.TXT
$!        PTY.PAS
$!        PTY_DOC.TXT
$!        PTY_EXAMPLE.C
$!        PYDRIVER.MAR
$!        TWDRIVER.MAR
$!
$!==============================================================================
$ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL )
$ VERSION = F$GETSYI( "VERSION" )
$ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK
$ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", -
    "VMS_SHARE V06.00 26-May-1988 requires VMS V4.4 or higher."
$ EXIT 44 
$VERSION_OK:
$ GOTO START
$
$UNPACK_FILE:
$ WRITE SYS$OUTPUT "Creating ''FILE_IS'"
$ DEFINE/USER_MODE SYS$OUTPUT NL:
$ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION -
    VMS_SHARE_DUMMY.DUMMY
b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) )
; s_file_spec := GET_INFO( COMMAND_LINE, "output_file" ); SET( OUTPUT_FILE
, b_part, s_file_spec ); b_errors := CREATE_BUFFER( "{Errors}" ); i_errors := 0
; pat_beg_1 := ANCHOR & "-+-+-+ Beginning"; pat_beg_2 := LINE_BEGIN 
& "+-+-+-+ Beginning"; pat_end := ANCHOR & "+-+-+-+-+ End"; POSITION
( BEGINNING_OF( b_part ) ); i_append_line := 0; LOOP EXITIF MARK( NONE 
) = END_OF( b_part ); s_x := ERASE_CHARACTER( 1 ); IF s_x = "+" THEN r_skip 
:= SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip <> 0 THEN s_x := ""
; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF; ENDIF
; IF s_x = "-" THEN r_skip := SEARCH( pat_end, FORWARD, EXACT ); IF r_skip <
> 0 THEN s_x := ""; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip := MARK( NONE )
; r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip <> 0 THEN POSITION
( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET ); MOVE_VERTICAL( 1 )
; MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part ) ); ENDIF; ERASE
( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF
; IF s_x = "V" THEN s_x := ""; IF i_append_line <> 0 THEN APPEND_LINE
; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF; i_append_line := 1; MOVE_VERTICAL
( 1 ); ENDIF; IF s_x = "X" THEN s_x := ""; IF i_append_line <
> 0 THEN APPEND_LINE; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF; i_append_line 
:= 0; MOVE_VERTICAL( 1 ); ENDIF; IF s_x <> "" THEN i_errors := i_errors + 1
; s_text := CURRENT_LINE; POSITION( b_errors ); COPY_TEXT
( "The following line could not be unpacked properly:" ); SPLIT_LINE; COPY_TEXT
( s_x ); COPY_TEXT( s_text ); POSITION( b_part ); MOVE_VERTICAL( 1 ); ENDIF
; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP r_x := SEARCH( "`", FORWARD
, EXACT ); EXITIF r_x = 0; POSITION( r_x ); ERASE_CHARACTER( 1 )
; IF CURRENT_CHARACTER = "`" THEN MOVE_HORIZONTAL( 1 ); ELSE COPY_TEXT( ASCII
( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDIF; ENDLOOP; IF i_errors = 0 THEN SET
( NO_WRITE, b_errors, ON ); ELSE POSITION( BEGINNING_OF( b_errors ) )
; COPY_TEXT( FAO( "The following !UL errors were detected while unpacking !AS"
, i_errors, s_file_spec ) ); SPLIT_LINE; SET( OUTPUT_FILE, b_errors
, "SYS$COMMAND" ); ENDIF; EXIT; 
$ DELETE VMS_SHARE_DUMMY.DUMMY;*
$ CHECKSUM 'FILE_IS
$ WRITE SYS$OUTPUT " CHECKSUM ", -
  F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!,passed." )
$ RETURN
$
$START:
$ FILE_IS = "000_README.TXT"
$ CHECKSUM_IS = 136808989
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
XThese files make up a pseudo terminal driver for VAX/VMS. This driver was
Xoriginally developed at Carnegie-Mellon University and has made the
Xrounds before as the CMU PTY driver.  I picked up the driver just after
Xit had been migrated from V3 to V4, made a lot of improvements, and have
Xbeen redistributing it ever since.
X
XThis driver runs under VMS V4 and V5.  It will not work under any VMS
Xprior to V4.  It has been minimally tested by me on V4.7 and V5.0.  It
Xshould work on earlier V4 point releases as well, but I haven't tried it.
X
XNote that for VMS V4 usage, you must edit the driver and remove the
Xcomment characters in front of the definition of the VMS_V4 symbol.  The
Xdefinition occurs on the 7th line of the driver source files.  This
Xdefinition must be commented out to build a VMS V5 compatible driver.
X
XSee PTY_DOC.TXT for documentation and NOTES.TXT for my additional comments
Xand observations.
X
XChanges for version 05-006A (PYDRIVER) and 05-004A (TWDRIVER) include:
X
X  o  Support for VMS V5 including Symmetric Multiprocessing environments.
X     Conditional assembly of the drivers will produce V4 or V5
X     compatible drivers.  This also includes changes to the PY$FDTWRITE
X     routine to be smarter about grabbing and releasing the device
X     (device IPL in V5, device lock in V5).  It used to raise and
X     lower IPL quite a lot, but this is expensive when converted to
X     lock/unlock for SMP.
X
X  o  The port control MULTISESSION bit is now set by the driver, causing
X     terminal sessions on TW devices to NOT count against your license
X     limit.  This is good for programs like PHOTO, but not so good
X     for network logins.  This really should be made settable by the
X     application controlling the PY device.
X
X  o  Writes to the PY device will now return SS$_DATAOVERUN if the TW
X     signals XOFF.  In the case of DATA OVER-RUN the bytecount field in 
X     the IOSB is the number of characters actually delivered. Note that
X     if the last character causes XOFF you will receive SS$_DATAOVERUN
X     instead of SS$_NORMAL.  Applications should check for SS$_DATAOVERUN
X     in the IOSB after a write to the PY device and keep track of how
X     many characters remain to be delivered later.  You probably want to
X     use the new flow-control AST mechanism, described below, in
X     conjunction with this so you know when to continue delivering data
X     to the PY device.
X
X  o  There is now a SETMODE and SETCHAR function that allows you to 
X     enable three new ASTs.  It does not take any function modifiers and
X     only sets the specified ASTs.  The QIO parameters are:
X
X`009`009P1 - ASTADDR
X`009`009P2 - ASTPARAM (16 bits only on TW$XON or TW$XOFF)
X`009`009P3 - ACCESS MODE to deliver AST in -- usual rules
X`009`009P4 - AST to deliver -- legal values are
X`009`009`0091 - Deliver AST when TW$XON is called.  When the 
X`009`009`009    AST is delivered the low order word of
X`009`009`009    ASTPARAM will be the character supplied to
X`009`009`009    TW$XON to send.  The high order word will
X`009`009`009    be your ASTPARAM.
X`009`009`0092 - Deliver AST when TW$XOFF is called.  When the
X`009`009`009    AST is delivered the low order word of
X`009`009`009    ASTPARAM will be the character supplied to
X`009`009`009    TW$XOFF to send.  The high order word will
X`009`009`009    be your ASTPARAM.
X`009`009`0093 - Deliver AST when TW$SET_LINE is called.
X
X  o  The TW device now defaults to HOSTSYNC.  This may be disabled
X     with a SET TERM DCL command or the proper SETMODE or SETCHAR
X     QIO to the TW device.  The TW device is always set NOMODEM and
X     will not allow MODEM to be set.
X
X  o  The PY device now accepts a SENSEMODE and SENSECHAR QIO function
X     to read the device characteristics of the TW terminal device.
X     These work exactly the same as they would to a terminal device.
X     The IOSB and return data buffer have the same format.  This allows
X     the controlling application to track the state of the associated TW
X     device.
X
X     NOTE:  Because SENSEMODE now returns TW terminal characteristics,
X            you can no longer use it to return the PY device dependent
X            longword which contains the unit number for the associated
X            TW device.  You must use $GETDVI instead.  You should already
X            have been using $GETDVI.
X
X  o  Modification to slave terminal device ownership to function
X     correctly after "Security Upgrade V2" has been applied to a
X     VMS V4 system.  The security upgrade is incorporated into V5.
X
X     The security upgrade fixed a bug whereby cloned terminal devices
X     were not protected in accordance with the system-wide terminal
X     protection mask, but were left wide open.  Cloned terminals are
X     no longer G,W:RWLP.  This caused some PTY applications to break,
X     since they needed access to the created terminal device without
X     privileges.  This version of the PTY drivers sets the device owner
X     of the cloned terminal device to that of the creator.  This should
X     allow applications that were sensitive to the device protection to
X     continue to function.  Additionally, the device remains inaccessible
X     to GROUP and WORLD, in keeping with system security requirements.
X
X     Other solutions to this problem have been proposed which merely force
X     the terminal protections wide open.  This is not a good idea as it
X     circumvents system security requirements.
X
X  o  The terminal device name has been changed from TPAn: to TWAn: because
X     the VAX PSI product now uses TP.  PY and TW are the names of choice
X     now since they have been registered within Digital by a development
X     group.  Some applications which are hard-coded for TPAn: or some
X     other name are going to break.  Perhaps they should have used a
X     logical name to refer to the device in the first place.  Oh well.
X
X     Source code is available for such applications (the two types of
X     PHOTO utility come to mind) and will have to be changed.  Alternately,
X     it is a simple patch to the executable if source code is not
X     available.  Finally, you may be able to get by with defining TPA0
X     to be TWA0 if you cannot fix or patch but this is may cause problems
X     if you use VAX PSI.  I urge anyone distributing an application which
X     will break due to this change to fix their application and make it
X     available again.
X
X     Please note that not all applications of PTY need to know the
X     terminal device name.  The TEK-CMU IP/TCP package, at least in
X     V6.0 with which I am familiar, uses PTYs but does not care what
X     the terminal device name is.
X
X     On a final note, if the results of the Digital development effort which
X     is using PY and TW should find their way onto your system, you
X     should be able to continue to use your applications with the Digital
X     supplied devices.  I will do my best to keep abreast of developments
X     in that arena and make public any caveats I find with the Digital
X     supplied devices.  At the worst, the DEC devices may be completely
X     changed, and we will change the names of PY and TW again.  Note that
X     this may be the time for you application writers to use (properly
X     prefixed -- naturally) logical names for your pseudo-terminal
X     device specifications.
X
X`009/Kevin Carosso                     kvc@nrc.com
X`009 Network Research Co.              kvc@ymir.bitnet
X
X`009June 9, 1988
X
XPS:
X
XIn case anyone has a REALLY old version, here's the notes from my
Xprevious distribution (note the date at the bottom).  These changes,
Xwhere applicable, are all incorporated into the current distribution.
X
X---------------------------------------------------------------------
X
XThe distribution version 04-006 fixes the following problems:
X
X  o  ^S^Y system crasher
X  o  randomly munged <LF> and <ESC> characters
X  o  SHOW DEVICE stack dumps
X  o  system crashes due to attempted use of the TPA0: device
X  o  terminal device name changed from PTAn: to TPAn: because
X     VMS uses PTA for MSCP tapes.
X
X`009/Kevin Carosso              kvc@engvax.scg.hac.com
X`009 Hughes Aircraft Co.`009or  kvc%engvax@oberon.usc.edu
X
X`009 December 9, 1986
$ GOSUB UNPACK_FILE
$ FILE_IS = "BUILD.COM"
$ CHECKSUM_IS = 2087006555
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X$ macro twdriver
X$ macro pydriver
X$ link twdriver,driver/opt
X$ link pydriver,driver/opt
X$ exit
$ GOSUB UNPACK_FILE
$ FILE_IS = "DRIVER.OPT"
$ CHECKSUM_IS = 623735376
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
Xsys$system:sys.stb/select
Xbase=0
$ GOSUB UNPACK_FILE
$ FILE_IS = "NOTES.TXT"
$ CHECKSUM_IS = 2131451716
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
XThese notes document some caveats I have found.  This information
Xcomplements the documentation in PTY_DOC.TXT with some additional
Xobservations I've made.
X
XFirst of all, I want to grant credit to the original authors of the
Xdriver, they are listed at the beginning of the two source files.  In
Xprivate correspondence with Dale Moore at CMU, he has chosen to release the
Xdriver to the public domain.  There have been various incarnations of this
Xdriver in the past.  I started with a version that was modified to run
Xunder VMS V4 and cleaned it up and made CONNECT/DISCONNECT and HANGUP work
Xconsistently.  I also changed the device name of the terminal device from
XPTAn: to TPAn: because VMS now uses PTA0: for MSCP tapes.  This version
Xhas been modified further for VMS V5 and the terminal device name has been
Xchanged, once again, to TWAn: because VAX PSI has usurped TPAn:.
X
XThe previous distribution of the drivers had been tested on VMS V4.0 through
XV4.7.  This distribution has been tested under V4.7, V5 FT2, and V5.0.
X
XNote that the the conditional assembly for VMS_V4 must be commented out
Xand the driver reassembled and relinked for V5.  Also note that the
XLINK warning message
X
X  %LINK-W-USRTFR, image has no user transfer address
X
Xis normal for device drivers and should be ignored.
X
XLoad the two drivers as PYA0: and TWA0: using a SYSGEN command such
Xas:
X
X`009$ MCR SYSGEN
X`009SYSGEN> LOAD DISK:[DIRECTORY]TWDRIVER
X`009SYSGEN> LOAD DISK:[DIRECTORY]PYDRIVER
X`009SYSGEN> CONNECT TWA0/NOADAPTER/DRIVER=TWDRIVER
X`009SYSGEN> CONNECT PYA0/NOADAPTER/DRIVER=PYDRIVER
X
XAssigning a channel to PYA0: will create a PYAn: and a TWAn:
Xpseudo-terminal pair (the unit numbers just go up).  Anything you write to
Xthat channel appears on the TW as if typed at a terminal.  Any output to
Xthe terminal TWAn: is available to be read from PYAn:.  On output, the
Xdevices do flow control between one another and all buffering.  You can
Xjust read, for example, with a 100 char buffer from PY and the read will
Xcomplete with whatever number of characters the QIO to the TW terminal
Xhad, anywhere from 1 to MAXBUF. If the QIO to the TW had more chars than
Xyour read buffer, it'll just fill the read buffer and return, and you can
Xget the rest on the next read.  On input, it is possible to overrun the TW
Xdevice's terminal type-ahead buffer, as it is with a real terminal.
X
XIf you assign a mailbox with the PYAn: device (use LIB$ASN_WTH_MBX
Xwhen assigning the channel to PYA0:) you will get an MSG$_TRMHANGUP
Xmessage in the mailbox whenever the terminal is hung-up.  This occurs
Xwhen a process deassigns the last channel to the device, just as a HANGUP
Xwill on terminals with modem signals.  You may ignore the hangup message if
Xyou choose and continue to use the device after the message.
X
XShould you deassign all channels to the PYAn: device, a hangup will be
Xforced on any process using the TWAn: device.  Just like dropping carrier on
Xa modem line.  If the pseudo-terminal is in use by an interactive process
Xand has an associated virtual terminal, the process will be disconnected,
Xotherwise the interactive process will be logged out.
X
XTo enable virtual terminals on pseudo-terminals, you must have the
XTT2$M_DISCONNECT bit set in the system default terminal characteristics
X(TTY_DEFCHAR2 in SYSGEN).
X
XNote that, just as with normal VMS terminals, you will only get a
XVTAn: if the line has the DISCONNECT terminal characteristic before
Xyou log into it, and only if you use LOGINOUT to start a process on
Xthe terminal.  Sending a <CR> into the pseudo-terminal device will
Xstart up LOGINOUT as it would on a real terminal.
X
XThere is currently one minor known bug in the drivers, a side-effect of
Xthe driver being cautious in order to prevent possible problems.  If you
Xhave a virtual terminal associated with the pseudo-terminal, and you
Xdeassign the last channel to the control device (the PY device) then a
XDISCONNECT is forced on any process on the TW and both devices should be
Xdeleted.  Currently, the TW will not disappear, though the PY will and
Xthe TW will be marked as OFFLINE.  This is because I rely on VMS to do
Xthe actual delete of the device and it appears that virtual terminals
Xscrew up the way device reference counts work, so VMS never gets around to
Xdeleting the device.  It is marked for delete, so anything you do (I like
XSHOW TERM TWA53:, for example) will cause it to disappear.  I could fix this
Xby zapping the device explicitly after forcing the DISCONNECT, however I
Xam not convinced that someone, somewhere, won't try to reference the UCB and
Xthus cause bad things to occur.  Note that it DOES get deleted correctly if
Xyou do not have a virtual terminal associated with the TW or if you have no
Xprocesses active on the TW when the PY and TW are to be deleted.  These two
Xcases are generally the norm.
X
XIt should be possible to set the TW terminal characteristics through
Xthe PY device, so the controlling program can set them.  
XThere may be ramifications of changing device characteristics on
XTTDRIVER unexpectedly, however, that have to be figured out first.
X
XIf you need to set characteristics of the terminal device right now,
Xyou must assign a channel to the TW device and use a SETCHAR QIO
Xthen deassign the channel before giving the TW to another process. You
Xwill get a HANGUP message in the associated mailbox when you
Xdeassign if the HANGUP attribute was set on the device.  You can
Xignore this message, however, and go ahead and use the device.
X
XThis is sufficient for most applications that need to set characteristics
Xonly before starting up another process to use the device.
X
XIf you need to set the characteristics after your other process has
Xassigned a channel to the terminal device, you will need the SHARE
Xprivilege to assign your own channel to it and do the SETMODE.  Note that
Xthe SETMODE QIO you do should be asynchronous as your QIO may get queued
Xbehind other QIO's and your application probably does not want to wait for
Xcompletion.
X
X`009/Kevin Carosso               kvc@nrc.com
X`009 Network Research Co.        kvc@ymir.bitnet
X
X`009 June 17, 1988  (supersedes NOTES.TXT dated December 9, 1986)
$ GOSUB UNPACK_FILE
$ FILE_IS = "PTY.PAS"
$ CHECKSUM_IS = 1629888086
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X(* Simple program to converse with the pseudo-terminal control device. *)
X
X[inherit ('SYS$LIBRARY:STARLET')]
Xprogram PTY;
X
Xconst
X  buffer_size = 256;
X  CTRL_BACKSLASH = chr (28);
X
Xtype
X  string = varying [256] of char;
X  unsigned_byte = [byte] 0..255;
X  unsigned_word = [word] 0..65535;
X  characteristic_buffer = packed record
X`009`009`009    dev_class, dev_type : unsigned_byte;
X`009`009`009    width : unsigned_word;
X`009`009`009    charbits, extended_bits : unsigned;
X`009`009`009  end;
X  status_block = packed record
X`009`009   status, count, terminator, terminator_size : unsigned_word;
X`009`009 end;
X
Xvar
X  stat : integer;
X  mbx_chan, tt_chan, pty_chan : [static, volatile] unsigned_word;
X  input_char : [static, volatile] char;
X  buffer : packed array [1..buffer_size] of char;
X  mbx_buffer : [static, volatile] packed array [1..40] of char;
X  term_chars, old_term_chars : [static, volatile] characteristic_buffer;
X  in_iosb, out_iosb, mbx_iosb : [static, volatile] status_block;
X  exit_descriptor : [static] packed record
X`009`009      flink : unsigned;
X`009`009      handler : unsigned;
X`009`009      argnum : integer;
X`009`009      reason : ^integer;
X`009`009    end := (0, 0, 1, nil);
X  message : [static, volatile] string :=
X`009`009`009`009''(13, 10, 7)'Got a mailbox message'(13, 10);
X
X{-----------------------------------------------------------------------------}
X
X  [external]
X  function LIB$ASN_WTH_MBX
X`009`009(DEVNAM : [class_s] packed array [l1..u1:integer] of char;
X`009`009 MAXMSG, BUFQUO : integer;
X`009`009 var DEVCHAN, MBXCHAN : [volatile] unsigned_word
X`009`009) : integer; extern;
X
X(*
X * CLEANUP is our exit handler.  It resets the terminal characteristics.
X *)
X
X  [unbound]
X  function Cleanup (reason : integer) : integer;
X
X  var
X    stat : integer;
X    iosb : status_block;
X
X  begin (* Cleanup *)
X    Cleanup := reason;
X    stat := $QIOW (CHAN := tt_chan,
X`009`009     FUNC := IO$_SETMODE,
X`009`009     P1 := old_term_chars,
X`009`009     P2 := size (old_term_chars));
X    if not odd (stat) then Cleanup := stat;
X  end; (* Cleanup *)
X
X  [asynchronous, unbound]
X  procedure Set_asynch_mbx_input; forward;
X
X(*
X * MBX_INPUT_AST is the AST handler invoked whenever we get something in
X * the associated mailbox.
X *)
X  [asynchronous, unbound]
X  procedure Mbx_input_AST;
X
X  var
X    stat : integer;
X    iosb : status_block;
X
X  begin (* Mbx_input_AST *)
X    if not odd (mbx_iosb.status) then $EXIT (mbx_iosb.status);
X
X    stat := $QIOW (CHAN := tt_chan,
X`009`009   FUNC := IO$_WRITEVBLK,
X`009`009   IOSB := iosb,
X`009`009   P1 := message.body,
X`009`009   P2 := message.length);
X    if not odd (stat) then $EXIT (stat);
X    if not odd (iosb.status) then $EXIT (iosb.status);
X
X    Set_asynch_mbx_input;
X  end; (* mbx_input_AST *)
X
X(*
X * SET_ASYNCH_MBX_INPUT issues an asynchronous read on the terminal.
X *)
X  procedure Set_asynch_mbx_input;
X
X  var
X    stat : integer;
X
X  begin (* Set_asynch_mbx_input *)
X    stat := $QIO (CHAN := mbx_chan,
X`009`009  FUNC := IO$_READVBLK,
X`009`009  IOSB := mbx_iosb,
X`009`009  ASTADR := mbx_input_AST,
X`009`009  P1 := mbx_buffer,
X`009`009  P2 := size (mbx_buffer));
X    if not odd (stat) then $EXIT (stat);
X  end; (* Set_asynch_mbx_input *)
X
X  [asynchronous, unbound]
X  procedure Set_asynch_input; forward;
X
X(*
X * INPUT_AST is the AST handler invoked whenever we get something in
X * from the terminal.  Just ship it to the PTY.
X *
X * One thing to note:  We are ignoring the fact that the PTY may return
X * SS$_DATAOVERUN if we fill up it's input buffer and it wants to XOFF us.
X * This should not really be a problem, since we tend to write one-char-at-
X * a-time.  We could also disable the HOSTSYNC characteristic on the pseudo
X * terminal, which causes it to never return the SS$_DATAOVERUN.  Either
X * way, data that doesn't fit into the typeahead buffer is lost.
X *
X * If the application wants input flow control, it should register for
X * the XON AST using an IO$_SETMODE QIO.  It should then check for
X * SS$_DATAOVERUN on writes, keep track of characters actually delivered,
X * as specified in the "count" field of the IOSB, and deliver the rest of
X * the characters when we get XON'ed again.  It should also not attempt
X * to deliver any additional data to the PTY until the XON AST happens.
X *)
X  [asynchronous, unbound]
X  procedure Input_AST;
X
X  var
X    stat : integer;
X
X  begin (* Input_AST *)
X    if not odd (in_iosb.status) then $EXIT (in_iosb.status);
X    if input_char = CTRL_BACKSLASH then $EXIT (SS$_NORMAL);
X
X    stat := $QIOW (CHAN := pty_chan,
X`009`009   FUNC := IO$_WRITEVBLK,
X`009`009   IOSB := in_iosb,
X`009`009   P1 := input_char,
X`009`009   P2 := 1);
X    if not odd (stat) then $EXIT (stat);
X    if (not odd (in_iosb.status) and (in_iosb.status <> SS$_DATAOVERUN)) then
X      $EXIT (in_iosb.status);
X
X    Set_asynch_input;
X  end; (* Input_AST *)
X
X(*
X * SET_ASYNCH_INPUT issues an asynchronous read on the terminal.
X *)
X  procedure Set_asynch_input;
X
X  var
X    stat : integer;
X
X  begin (* Set_asynch_input *)
X    stat := $QIO (CHAN := tt_chan,
X`009`009  FUNC := IO$_READVBLK,
X`009`009  IOSB := in_iosb,
X`009`009  ASTADR := Input_AST,
X`009`009  P1 := input_char,
X`009`009  P2 := 1);
X    if not odd (stat) then $EXIT (stat);
X  end; (* Set_asynch_input *)
X
Xbegin (* PTY *)
X  stat := LIB$ASN_WTH_MBX (DEVNAM := 'PYA0:',
X`009`009`009    MAXMSG := size (mbx_buffer),
X`009`009`009    BUFQUO := 2 * size (mbx_buffer),
X`009`009`009    DEVCHAN := pty_chan,
X`009`009`009    MBXCHAN := mbx_chan);
X  if not odd (stat) then $EXIT (stat);
X
X  Set_asynch_mbx_input;
X
X  stat := $ASSIGN (CHAN := tt_chan, DEVNAM := 'TT');
X  if not odd (stat) then $EXIT (stat);
X
X(* Get terminal characteristics. *)
X
X  stat := $QIOW (CHAN := tt_chan,
X`009`009 FUNC := IO$_SENSEMODE,
X`009`009 P1 := term_chars,
X`009`009 P2 := size (term_chars));
X  if not odd (stat) then $EXIT (stat);
X
X  if term_chars.dev_class <> DC$_TERM then
X    $EXIT (SS$_IVDEVNAM);
X
X  old_term_chars := term_chars;
X
X(* declare exit handler so that terminal chars are restored *)
X
X  exit_descriptor.handler := iaddress (Cleanup);
X  new (exit_descriptor.reason);
X
X  stat := $DCLEXH (DESBLK := exit_descriptor);
X  if not odd (stat) then $EXIT (stat);
X
X(*
X * Set terminal characteristics we need:
X *    PASSTHRU, NOECHO, NOTTSYNC, NOHOSTSYNC
X *)
X
X  with term_chars do
X  begin
X    extended_bits := UOR (extended_bits, TT2$M_PASTHRU);
X    charbits := UOR (charbits, TT$M_NOECHO);
X    charbits := UAND (charbits, UNOT (TT$M_TTSYNC));
X    charbits := UAND (charbits, UNOT (TT$M_HOSTSYNC));
X  end;
X
X  stat := $QIOW (CHAN := tt_chan,
X`009`009 FUNC := IO$_SETMODE,
X`009`009 P1 := term_chars,
X`009`009 P2 := size (term_chars));
X  if not odd (stat) then $EXIT (stat);
X
X  Set_asynch_input;
X
X  repeat
X    stat := $QIOW (CHAN := pty_chan,
X`009`009   FUNC := IO$_READVBLK,
X`009`009   IOSB := out_iosb,
X`009`009   P1 := buffer,
X`009`009   P2 := size (buffer));
X    if not odd (stat) then $EXIT (stat);
X    if not odd (out_iosb.status) then $EXIT (out_iosb.status);
X
X    stat := $QIOW (CHAN := tt_chan,
X`009`009   FUNC := IO$_WRITEVBLK,
X`009`009   IOSB := out_iosb,
X`009`009   P1 := buffer,
X`009`009   P2 := out_iosb.count);
X    if not odd (stat) then $EXIT (stat);
X    if not odd (out_iosb.status) then $EXIT (out_iosb.status);
X  until false;
Xend. (* PTY *)
$ GOSUB UNPACK_FILE
$ FILE_IS = "PTY_DOC.TXT"
$ CHECKSUM_IS = 202726263
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X 
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X             Pseudo Terminal release notes
X
X
X
X
X
X             This document briefly describes a VAX/VMS Pseudo Terminal. It
X             contains information about the device, a programming chapter, user
X             interface section, and instructions on compiling and installing
X             the drivers.
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X`012
X 
X
X
X
X
X
X
X
X
X          Contents
X
X
X          CHAPTER 1  INTRODUCTION                                           1-1
X
X               1.1  USES OF PTYS                                            1-1
X
X               1.2  CONCEPT OF CONTROL AND TERMINAL DEVICE                  1-2
X
X               1.3  SIMILARITIES BETWEEN PTYS AND TERMINALS                 1-2
X
X               1.4  DIFFERENCES BETWEEN PTYS AND TERMINALS                  1-3
V                     1.4.1  Device Characteristics                           1-
X3
V                     1.4.2  Device Type                                      1-
X4
V                     1.4.3  Device Class                                     1-
X4
V                     1.4.4  TW Unit Number                                   1-
X4
X
X          CHAPTER 2  USING THE PTY                                          2-1
X
X               2.1  CREATING A PTY                                          2-1
X
X               2.2  READING DATA                                            2-2
X
X               2.3  WRITING DATA                                            2-3
X
X               2.4  SPECIAL SIGNALS                                         2-4
X
X               2.5  PROBLEMS                                                2-4
X
X          CHAPTER 3  PTY FUNCTION CODES                                     3-1
X
X               3.1  READ                                                    3-1
X
X               3.2  WRITE                                                   3-2
X
X               3.3  SET MODE AND SET CHARACTERISTICS                        3-3
X
X               3.4  SENSE MODE AND SENSE CHARACTERISTICS                    3-4
X
X               3.5  I/O STATUS BLOCK                                        3-5
X
X
X
X
X
X
X
X                                                                            iii
X`012
X 
X
X
X          Contents
X
X
X
X
X          CHAPTER 4  BUILDING AND INSTALLING THE PTY                        4-1
X
X               4.1  COMPILING SOURCES                                       4-1
X
X               4.2  INSTALLING THE DEVICES                                  4-2
X
X
X          FIGURES
X               3-1  Sense Mode and Characteristics Buffer                   3-5
X               3-2  IOSB Contents - Read and Write Function                 3-5
X               3-3  IOSB Contents - Set Mode and Characteristics
V                     Functions                                               3-
X6
X               3-4  IOSB Contents - Sense Mode and Characteristics
V                     Functions                                               3-
X6
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X          iv
X`012
X 
X
X
X
X
X
X
X
X
X
X
X
X
X
X          Chapter 1
X
X
X          Introduction
X
X
X
X
X             This chapter describes the use of the VAX/VMS Pseudo Terminal
X             Driver as implemented at Carnegie-Mellon University Computer
-+-+-+-+-+ End of part 1 +-+-+-+-+-
