[net.unix-wizards] Getting 'getty' to hangup dialup lines.

mlg@ipms.UUCP (Mike Greenberg) (08/01/84)

I added the line
	ioctl(0,TIOCHPCL,0);
to getty.c to cause dialup lines to hangup when a user logs out.

For some unknown reason that does not work all of the time.  Does
anybody have any idea why?

We are running bsd4.1 on a vax11/750 and using DF03's for dialup
units.

Please resply via mail.
-- 
Mike Greenberg 		USENET: ..decvax!sultan!ipms!mlg 
			ARPA: ipms!mlg@cmu-ri-isl 	ENET: cdr::greenberg

smh@mit-eddie.UUCP (Steven M. Haflich) (08/02/84)

[]	I added the line
		ioctl(0,TIOCHPCL,0);
	to getty.c to cause dialup lines to hangup when a user logs out.

	For some unknown reason that does not work all of the time.  Does
	anybody have any idea why?

	We are running bsd4.1 on a vax11/750 and using DF03's for dialup units.

Most 4.? system sources I have examined come with the line
	tp->t_state |= TS_HUPCLS;
commented out (e.g. in dz.c).  Otherwise the kernel would set HUPCLS as
the default state at first open.  Can anyone suggest why it might have
been disabled?  The only effect is that after logout on a dialup line,
one has to redial.  This inconvenience is outweighed by the protection
against having dialups hung by users who forget to "hang up".

Anyway, the likely reason it *sometimes* doesn't work, regardless:  I
have no experience with the DF03, but modems usually low pass filter
transients of state changes.  "Hanging up" consists of dropping DTR to
the modem, but the modem may fail to disconnect if DTR is dropped only
very briefly.  What could be happening is that when the user "shell"
process exits and the tty is closed, invoking HUPCLS and dropping DTR,
init wakes up and reopens the line immediately.  DTR is not unasserted
long enough for the modem to see it and believe it.

This can be fixed by placing a "sleep(2);" in front of the multi-user
tty open in the init process itself.

Steve Haflich

dmmartindale@watcgl.UUCP (Dave Martindale) (08/07/84)

Another reason (the most common one here) that modems don't hang up
when someone logs off is this:

The hangup is done when the last process that has that terminal open
exits, NOT when the user logs off.  If the last-on user left a background
process running without explicitly redirecting stdin, stdout, and stderr,
then the tty is still open, and the hangup doesn't happen.  Or a previous
user who logged on last week may have left a process around - as long as
it's still running, it will prevent the hangup from happening.

Note that vhangup() prevents such background processes from reading from
or writing to the tty, but they still have an open descriptor.
The right way to fix this is to modify vhangup() to eliminate those
pointers to the tty entirely, either in u_ofile or by changing the
entries in the file table, but it isn't simple.

chris@umcp-cs.UUCP (08/11/84)

I've been thinking about changing the vhangup system call to switch the
file descriptor over to an inode to /dev/null.  Here's my idea:  have
init call vhangup with a file descriptor that is open on /dev/null.
Have vhangup switch the inode given by the file pointer connected to
the terminal in question and the inode given by the file pointer given
to the vhangup system call.  Some fiddling with f_counts would need to
be done, of course, if multiple instances of the hung-up terminal are
lying around.  Finally, when the vhangup returns, init can just close()
the file descriptor, which will either point to /dev/null (no instances
of the hung-up terminal found) or to the terminal being hung-up.

Does anyone know of any potential problems with this (aside from init
compatibility issues)?
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci (301) 454-7690
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

bass@dmsd.UUCP (John Bass) (08/14/84)

Chris,
	I implemented the equivalent of vhangup in 1977/78 at SRI with
a slightly different syntax ... fswtch(old_fd,new_fd) where all references
of the inode pointed to by old_fd file descriptor where replaced with
the reference to the new_fd file descriptor inode. Init on that
system left a watchdog process to adopt all orphan children for accounting
reasons, and did the switch when sent a hangup signal or the
"getty/login/shell" process terminated. Everything worked fine except for
a few programs that didn't die with hangup and looped forever reading dev/null.
It was also necessary to sleep for a couple seconds to MAKE SURE the modem
or MUX dropped the line ... and it stayed dropped.

	The action of replacing one inode with a named other was useful
also for moving one login session to another terminal line ( a particularly
useful feature for a number of reasons). It also enables being able to
switch FILES on some running program ... particularly useful for diverting
STDIN and STDOUT between pipes of children processes.

	The fix allowed detached jobs to complete without holding up
the line on a mux or modem ... IE last close for a logout really drops
DTR all the time.

	It is useful to implement /dev/die as a modification of /dev/null
which generates eof, then SIGHUP, then SIGKILL based on a upage state
variable which is incremented for each read to the device for that process.
All writes are just like a normal /dev/null action. This action makes it
a fatal error to loop on the "terminal input" ignoring SIGHUP and EOF.

NOTE: for anyone still running OLD systems ...
Part of the problem is that some systems like PDP's without floating point
discard hangup signals when trapping for floating point emulation. Other
processes which use event driven actions based on SIGNALS have similar
problems ... thus on HANGUP ... not every process will get the hangup
signal -- NOTE: that this is only a problem for some older systems,
most signal handling in newer systems uses a bit map for posting signals.
(Back in the OLD days with V5/V6 life was tough ... remember 50 fixes?)

John Bass

dbj@RICE.ARPA (08/16/84)

From:  Dave Johnson <dbj@RICE.ARPA>

	I added the line
		ioctl(0,TIOCHPCL,0);
	to getty.c to cause dialup lines to hangup when a user logs out.

	For some unknown reason that does not work all of the time.  Does
	anybody have any idea why?

The reason that this doesn't work some times is that the device close
routine (which is responsible for actually dropping DTR after you've done a
TIOCHPCL) does not get called by the kernel until the last file descriptor
is closed to that device.  If there are processes running in the background
on that terminal when you log off, they will most likely still have files
open to the terminal, and thus the device close routine does not get called
and the line does not get hung up.  Alas, vhangup() does not dissassociate
the background processes from the terminal enough to convice the rest of the
kernel to call the device close routine or to call it itself to get the
hang up effect.

Currently, the only real way to fix this would be to carefully run
background processes with their standard input, output and error redirected
somewhere other than the terminal, such as to /dev/null with

        process </dev/null >&/dev/null &

                                        Dave Johnson
                                        Dept. of Computer Science
                                        Rice University
                                        dbj@rice.ARPA

chris@umcp-cs.UUCP (08/21/84)

The ``fswtch'' system call sounds a lot like Rehmi Post's hack for
doing the same.  Only his runs in user mode -- now THAT'S living
dangerously.  Obviously such a system call has to be restricted to
the super user . . . (``Whaddaya mean, he read my password by switching
my terminal and his!?'')
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci (301) 454-7690
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland