Subject: Re: pcvt and TIOCCONS
To: None <Chris_G_Demetriou@UX2.SP.CS.CMU.EDU>
From: Gordon W. Ross <>
List: current-users
Date: 04/18/1996 15:17:16
> Cc: gwr,,,
> Date: Wed, 17 Apr 1996 01:17:37 -0400
> From: Chris G Demetriou <Chris_G_Demetriou@UX2.SP.CS.CMU.EDU>
> [ ... behind on my e-mail. ]
[ ... and I've been busy at work... -gwr ]

> I figure, you should be able to specify a set of commands that will be
> run at logout from a tty, and a set of devices to change modes on
> etc., in a well-defined way.
> Any or all of those commands could be a shell-script, custom binary,
> or who knows what.
> My point is, only minimal policy should be encoded in the file.  In
> particular, i think that the following is "OK":
> 	(1) login to a certain tty may cause certain actions to be taken,
> 	(2) log-out from a tty may cause certain actions to be taken.
> I _DO NOT_ want the set of actions to be constrained to a certain set
> of built-in functions (like 'chown', 'chmod', and 'unmount').

OK, I have a new functional specification to propose, that I hope
will provide all the flexibility you desire.  Here it is:

Actions to be performed at login and logout time would be controlled
by two files: /etc/tty_login and /etc/tty_logout respectively.  Both
would use the same format, and would be processed by a single library
function to be added to libutil.  The file format would be lines of
the form:

	# comment line
	tty_name	shell_command

The format could (optionally) be extended to allow multi-line
commands by continuing onto the next line when a backslash is
the last character on the line.  [ Is this desirable? ]

The tty_name would be matched against the name of the current
tty line so all lines (and only those lines) with he tty_name
field matching would be processed.

The shell_command field would be run as 'sh -c "shell_command"'
with the following environment variable guaranteed to be set:


This format allows simple commands to be specified directly as
a shell command, and more complicated processing could be done
with an external program.  Here are examples of each:

Example /etc/tty_login file:
	# This line just needs one related device chown'ed
	/dev/wsconsole		chown ${USER} /dev/wsmouse
	# This line has several related devices, which are
	# handled by the external program /etc/
	/dev/kdconsole		/etc/ login

Example /etc/tty_logout file:
	# This line just needs one related device chown'ed
	/dev/wsconsole		chown root /dev/wsmouse
	# This line has several related devices, which are
	# handled by the external program /etc/
	/dev/kdconsole		/etc/ logout

Here is an example of an external program /etc/

	# Just chown this list of devices, if each exists.
	# The new owner name comes from the environment.
	[ "$USER" ] || { echo "$0: USER not set" ; exit 1; }
	for d in $devs
		chown $USER $d
		chmod 600 $d
	exit 0

Here is a proposed interface for the new libutil function:

void tty_relatives(char *filepath, char *ttyname, char *username);

	filepath: one of:
		_PATH_TTY_LOGIN 	("/etc/tty_login")
		_PATH_TTY_LOGOUT 	("/etc/tty_logout")
	ttyname:  name of the tty getty runs on (i.e. /dev/console)
	username:  text representation of UID, i.e. "root" or "gwr"

The above function would be called by src/usr.bin/login/login.c
just after it does the chown call to the tty line, i.e.:

	tty_relatives(_PATH_TTY_LOGIN, ttyn, pwd->pw_name);

The same function would also be called by getty in main.c as:

	tty_relatives(_PATH_TTY_LOGOUT, ttyn, "root");

just after it does its chown/chmod calls for the tty line.

The implementation of tty_relatives() would be roughly:

	Open filepath
	do {
		read line (and maybe continuations)
		if line matches ttyname {
			fork; parent waits;
			child does {
				putenv("USER", username);
	} while (not end of file)

There may be better ways to communicate the various pieces of
information like $USER in the call to tty_relatives(), and the
name of that function is certainly open to improvments...