Path: utzoo!utgpu!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!ames!xanth!nic.MR.NET!tank!mimsy!chris
From: chris@mimsy.UUCP (Chris Torek)
Newsgroups: comp.unix.wizards
Subject: Re: vhangup
Message-ID: <14846@mimsy.UUCP>
Date: 5 Dec 88 02:14:25 GMT
References: <13@cmdfs2.intel.com> <2246@bucsb.UUCP> <5197@mit-vax.LCS.MIT.EDU> <9124@rpp386.Dallas.TX.US>
Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742
Lines: 43

In article <9124@rpp386.Dallas.TX.US> jfh@rpp386.Dallas.TX.US (The Beach Bum)
asks:
>Why can't the file just be closed?  Why wasn't this done?

Here is how vhangup() is currently implemented:

	for (f in file_table)
		if (f->f_type is an inode)
			if (f as an inode is a device && is u.u_ttyd)
				f->f_flag &= ~(FREAD|FWRITE);

Simple, if unelegant.

Suppose we were to try to close it:

			if (f device is u.u_ttyd)
				xxx

xxx cannot simply be `closef(f)'; the other process's u. area still
refers to f.  If the same file table slot is later used for (say)
/etc/passwd, all sorts of things might go wrong.  Besides, this file
table entry might be referenced from any number of u.u_ofile[] entries.
(In fact, it will have f->f_count such references.)

What we can do is swap:

	oldip = NULL;
	newip = inode_for("/dev/null");
	for (f in file_table)
		if (f->f_type is an inode)
			if (f as an inode is a device && is u.u_ttyd) {
				oldip = (struct inode *)f->f_data;
				f->f_data = (caddr_t)newip;
			}

	/* oldip==NULL => caller did not have control terminal open */
	if (oldip)
		error = closei(oldip dev, mode, flag);

except that this is not quite all that needs doing.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris