Skip site navigation (1)Skip section navigation (2)
Date:      Sun,  6 Oct 96 22:23:26 +0000
Subject:   Advice wanted - how to drive ptys
Message-ID:  <"6472-961006221906-328B*/G=Andrew/S=Gordon/O=NET-TEL Computer Systems Ltd/PRMD=NET-TEL/ADMD=Gold 400/C=GB/"@MHS>

Next in thread | Raw E-Mail | Index | Archive | Help
I have a terminal-server application that drives the master side of a bunch of ptys; in the current setup, the program on the slave side is always telnet.   In my test setup, all works perfectly.  However, when used for real it intermittently suffers a problem where the slave process apparently does not die when the pty master is closed.  Normally this is harmless, only noticeable in that there can be several telnet processes belonging to one terminal which "can't happen".  If enough of these build up (invariably when I am not on site to observe what happens) somthing goes wrong - probably running out of pty devices, or hitting the per-user process limit - and the whole thing stops working.

Full details are below; any hints/suggestions would be welcome.  Am I right in thinking that closing the master side of a pty is enough to clean up the slave side in normal circumstances?  rlogind doesn't seem to do anything special.


Andrew Gordon


The setup is a 486 with an interface to an obsolete/proprietary network
(Acorn Econet) and a normal ethernet interface.  At present it is doing
nothing apart from running my terminal server application.  The terminal
server accepts incoming connections from terminals on Econet and connects
them through ptys to copies of telnet, allowing them to login to shell
accounts on another FreeBSD machine accessible over the ethernet.

The server uses the forkpty() function from libutil to open the ptys, and
then on the child side uses exect() to execute telnet with suitable
arguments to connect immediately to the shell machine.  The main loop of the
server sits in select(), waiting on activity from the Econet or for any of
the ptys to become readable/errored (or writable if there is data queued).

Since the users are an aggressive lot (this is in a school), they may well
terminate a session by pressing reset on their terminals rather than logging
out properly.  The protocol on the Econet side only allows a single session
from each terminal to the server, and sends keep-alive packets once a
minute, so there are a number of ways a session can be terminated:

1) Normal logout.  The telnet process exits, causing the pty master to
   be returned from select as errored.  The server then closes the pty
   master and sends a disconnect to the terminal.

2) Terminal does not respond to 'keep-alive' packet, or has remained
   in a flow-control blocked state for too long (probably because the
   terminal has been reset or powered off).  The server simply closes the
   pty master and erases the connection from its tables.  The telnet
   process sees its tty hangup, and exits.

3) A connect request arrives from a terminal which already has a connection
   active (probably due to the user pressing reset and immediately
   re-running the terminal software before the timeouts occur).
   The server closes the pty master relating to the old session, and
   opens a new one as for a normal new connection.

The left-over telnets are almost always (according to "ps") idle in select, and can be killed manually.  I have once seen one stuck in "IE" state on ps, though not recently.  All the telnet processes (both the active ones and the unwanted ones) have distinct pty devices as their controlling ttys.

I am fairly sure that the users are not subverting the telnet processes to run anything else on this machine - they could in principle type ^] to break out to the telnet prompt and get a shell, but I don't think they are doing this and in any case I can't think of anything they could do in a sub-shell that would lead to this.

Want to link to this message? Use this URL: <"6472-961006221906-328B*/G=Andrew/S=Gordon/O=NET-TEL Computer Systems Ltd/PRMD=NET-TEL/ADMD=Gold 400/C=GB/">