[comp.unix.wizards] is this wise?

root@chessene.UUCP (Mark Buda) (04/30/89)

Consider this (and ignore the lack of error checking):

/* finger.c */
#include <stdio.h>
main()
{
FILE *f;
int c;
f = fopen("/dev/hosts/uunet.uu.net/tcp/79", "r+");
fprintf(f, "\r\n");
while ((c = getc(f)) != EOF) putchar(c);
fclose(f);
}

There. Isn't that much nicer than sockets?

Mark Buda
hermit@chessene.uucp
hermit%chessene.uucp@uunet.uu.net
...!rutgers!bpa!vu-vlsi!devon!chessene!hermit
devon.lns.pa.us!chessene!hermit

dave@micropen (David F. Carlson) (05/03/89)

In article <378@chessene.UUCP>, root@chessene.UUCP (Mark Buda) writes:
! Consider this (and ignore the lack of error checking):
! 
! FILE *f;
! f = fopen("/dev/hosts/uunet.uu.net/tcp/79", "r+");
! fprintf(f, "\r\n");
! fclose(f);
! 
! There. Isn't that much nicer than sockets?

Writing on a FILE opened for reading is never nicer than sockets.

-- 
David F. Carlson, Micropen, Inc.
micropen!dave@ee.rochester.edu

"The faster I go, the behinder I get." --Lewis Carroll

schwartz@shire.cs.psu.edu (Scott Schwartz) (05/04/89)

In article <378@chessene.UUCP>, root@chessene (Mark Buda) writes:
>f = fopen("/dev/hosts/uunet.uu.net/tcp/79", "r+");

How about "/dev/ip/192.48.96.2/tcp/79"?

Hey, doesn't VMS do something like that?  (shudder.)
-- 
Scott Schwartz		<schwartz@shire.cs.psu.edu>

rick@uunet.UU.NET (Rick Adams) (05/04/89)

> f = fopen("/dev/hosts/uunet.uu.net/tcp/79", "r+");
> There. Isn't that much nicer than sockets?

Why not:
	f = tcp_open("uunet.uu.net", "finger", "r+w"):

That way the underlying structure doesn't matter. You can have
sockets, tli, streams, your filesytem like layout.

Why force the user to file name like contruct when it doesn't
fit nicely.

The tcp_open variation could even be run on a non-unix system
by only writing the tcp_open library routine.

After all, what you REALLY want is to open a tcp connection to
the finger port on uunet. I'd say my version makes that a LOT
clearer than deciphering the filename.

Abstractions are fine, but there no point in forcing tihngs that
dont fit.

---rick

berry@loiosh.s1.gov (Berry Kercheval) (05/04/89)

In article <693@micropen>, dave@micropen (David F Carlson) writes:
>In article <378@chessene.UUCP>, root@chessene.UUCP (Mark Buda) writes:
>! Consider this (and ignore the lack of error checking):
>! 
>! FILE *f;
>! f = fopen("/dev/hosts/uunet.uu.net/tcp/79", "r+");
>! fprintf(f, "\r\n");
>! fclose(f);
>! 
>! There. Isn't that much nicer than sockets?
>
>Writing on a FILE opened for reading is never nicer than sockets.

Um, try R'ing TFM.  That is opened for UPDATE (reading and writing).

  --berry

guy@auspex.auspex.com (Guy Harris) (05/04/89)

>There. Isn't that much nicer than sockets?

You haven't given us enough information to answer your question.  I have
no idea how "open" is to perform the appropriate TCP operations, given
that path.

If the ability to translate "uunet.uu.net" into an Internet address is
buried in the kernel, resolver and all, then no, it's not nicer than
sockets.  (If you have to manually construct the directory hierarchy,
rather than it automagically coming from the current host
database/server, it's *definitely* not nicer than sockets.)

If it's done outside the kernel, well, it has some nice properties
(although why is it "79" and not "finger"?).  Asking whether it's "nicer
than sockets" isn't necessarily appropriate; the question is whether
it's nicer than "socket"+"connect", since that's all you've replaced. 
If you want your mechanism to be compared with sockets, you'll have to
provide replacements for other mechanisms in sockets, such as "bind",
"accept" (newly-spawned descriptor for the connection and all), etc..

clyde@ut-emx.UUCP (Clyde W. Hoover) (05/04/89)

Deja-vu!  In the old days when the ARPANET used NCP and the highest UNIX release
was V6, (anyone remember 'smalldaemon' and 'largedaemon'?) a 
version of the UIUC networking code worked much like that.

To open a network connection, one did something like:

	fd = open("/dev/net/sri-nic", 2, &mumble);
	/*
	 * Host number was in the inode - either minor device # or in the
	 * direct block list - major device number was 'network'
	 */

Which evolved to (still pre-TCP):

	mumble.addr = host-number;
	mumble.timeout = XXX;
	mumble.slag = slag;
	fd = open("/dev/network", 2, &mumble);

Which with the advent of TCP and multiple protocol suites evolved into the socket
idea currently in use.

Can you IMAGINE having EVERY hostname AND alias AND IP-number out there in your
/dev?  Or modifying namei to recognize "/dev/network" and not actually require
all those files to exist?  Ugh.  As troublesome as setting up sockets can be,
they are so much better than anything that came before (I know, I've messed with
much of what came before).

Commonly available convience routines would be nice, however.
Take 20 minutes and write some.  Take 2 hours and document them.

	-Clyde Hoover

Shouter-To-Dead-Parrots @ Univ. of Texas Computation Center; Austin, Texas  
	clyde@emx.utexas.edu; ...!cs.utexas.edu!ut-emx!clyde

Tip #268: Don't feel insecure or inferior! Remember, you're ORGANIC!!
	  You could win an argument with almost any rock!

jfh@rpp386.Dallas.TX.US (John F. Haugh II) (05/05/89)

In article <53756@uunet.UU.NET> rick@uunet.UU.NET (Rick Adams) writes:
>> f = fopen("/dev/hosts/uunet.uu.net/tcp/79", "r+");
>> There. Isn't that much nicer than sockets?
>
>Why not:
>	f = tcp_open("uunet.uu.net", "finger", "r+w"):

Because you could point to that file with a symbolic link and
give it a more worthwhile name and have other programs have
other uses for it.

>That way the underlying structure doesn't matter. You can have
>sockets, tli, streams, your filesytem like layout.

But you have to have your mystery tcp_open() call.  What's
wrong with the open() call we have already?
-- 
John F. Haugh II                        +-Salad of the Week:-------------------
VoiceNet: (214) 250-3311   Data: -6272  | "Bring me a head of Romain lettuce"
InterNet: jfh@rpp386.Dallas.TX.US       | [ not said by ] -- Richard Sexton
UucpNet : <backbone>!killer!rpp386!jfh  +--------------------------------------

rick@uunet.UU.NET (Rick Adams) (05/06/89)

> wrong with the open() call we have already?

tcp_open() isn't a system call. It's a user level abstraction that
does what you want (i.e. a simpler interface to getting a tcp
socket).

You don't use the open() call because it doesnt fit well conceptually.
Why not force EVERYTHING to use open().

I can see it now:

	getpwuid(213) becomes open("/dev/password/213")
	gettimeofday() becomes open("/dev/clock")
	etc.

By your argument, we change everything to use open. (And if you
think the kernel is big now, wait until you move most of the
userlevel networking code into it)

--rick

scs@adam.pika.mit.edu (Steve Summit) (05/06/89)

In article <378@chessene.UUCP> root@chessene.UUCP (Mark Buda) writes:
>Consider this (and ignore the lack of error checking):
>/* finger.c */
>f = fopen("/dev/hosts/uunet.uu.net/tcp/79", "r+");

Shades of CHAOSnet.  (Is it still around?)

On a CHAOSnet system (I am not making this up), this would have
been something like*

	open("/dev/chc0/remotehost/fingerd", 0)

This required modifications to namei, to be sure, but less
sweeping than you might think, because /dev/chc0 (or whatever it
was called) was, if memory serves, a character-special directory
file (i.e. st_mode&S_IFMT was S_IFDIR|S_IFCHR).  Sublime and/or
ridiculous, but a "neat hack" all the same.

The server end of the Unix CHAOSnet implementation was nice, as
well; much closer (IMHO) to the "Unix Philosophy" than the
current jangled mess**.  Continuing with the above example, the
chaosnet listener daemon on machine "remotehost" would simply
exec /usr/lib/chaos/fingerd, with standard input and output
connected to the network stream.  Notice that services were
essentially named with names, not numbers; no /etc/services lists
and funny magic socket numbers were required.  If you wanted to
add a new service, all you had to do was stick it in your
/usr/lib/chaos directory and tell people about it; they could
"open" it right away.  (The daemons were generally simple to
write, as well.  "fingerd" could just be /bin/who, for instance.)

Accessing network services in this way is an overloading of the
open call, to be sure, but overloading is not necessarily a Bad
Thing.  The consensus seems to be that /dev/fd and /dev/proc, for
instance, are the cat's meow.  (I suspect that a remotehost and
service syntax built into a pathname could be implemented without
change to namei on a system with a file system switch or other
mechanism that makes things like /dev/proc possible.)

					     Steve Summit
					     scs@adam.pika.mit.edu

* The names "/dev/chc0" and "fingerd" are incorrect; it's been a
  long time and I can't remember what they really were.

** Okay, maybe not "jangled mess;" I guess the welter of daemons,
   one per service, most unused at any given time and
   accomplishing nothing except occupying process table slots and
   keeping swap space warm, has been more recently replaced with
   a single master daemon, which is a step in the right
   direction, but it still seems like there's a lot more hair
   than there has to be, and that the kernel is involved in too
   much of it.

bzs@bu-cs.BU.EDU (Barry Shein) (05/06/89)

From: rick@uunet.UU.NET (Rick Adams)
>tcp_open() isn't a system call. It's a user level abstraction that
>does what you want (i.e. a simpler interface to getting a tcp
>socket).

Appended below is some example code I put together for a systems
programming class I taught at BU a while back, it might not be perfect
but I think it shows the concept Rick describes is pretty easy to
implement.

This is for the server side but could easily be adapted for the client
side, in fact client is much simpler.

The fundamental question, whether or not the tcp network name space
should be merged with the unix file name space is much more
complicated.

I guess for starters I'd hate to see someone cook up a solution that
only works for (most likely some simple subset of) TCP without
considering network protocols in general (eg. UUCP, OSI, etc.) and
distributed processing in general (the line between two processes
cooperating across a network and multiple processes cooperating on one
machine, particularly in a multiprocessor environment, can be very
subtle.)

It also is not very hard to write a version of open() which snoops the
pathname and decides whether or not to simulate TCP in the file name
space or to just pass the name to the real open() as a library
routine. I'd like to see that experiment done and a bunch of real
applications made to use it before deciding the whole thing can be
thrown into the file system. I'll bet lots of issues start to get in
the way and it turns out to be a lot harder than it seems, tho
probably not impossible (ITS and TWENEX had file name space TCP
implementations, I remember TWENEX's implementation required some
bizarre things to be put into the name to handle various options, it
was discouraging to say the least.)

	-Barry Shein, Software Tool & Die

----------

/*
 *	Establish() me as a network server, return socket to
 *	accept() connections on or error. Args are same as for
 *	getservbyname() [see UNIX/4.2 PM (3)]
 *	Actually, if we were willing to be less generic some of this
 *	could be simplified.
 */
SOCKET
establish(service,protocol) char *service, *protocol;
{
	SOCKET s ;
	struct sockaddr_in sa ;
	struct hostent *hp ;
	struct protoent *pp ;
	struct servent *sp ;

	/* clear out the socket structure */
	bzero(&sa,sizeof sa) ;
	/* find out our host's info into hp */
	hp = gethostbyname(myname) ;
	if(hp == NULL) goto bad ;	/* oops, we don't exist? */
	/* get the tcp protocol info */
	if((pp = getprotobyname(protocol)) == NULL) goto bad ;

	/*
	 *	Note: we'll use this later, for now let UNIX
	 *	assign us a socket number to listen on
	 *
	if((sp = getservbyname(service,protocol)) == NULL) goto bad ;
	 */
	/* set up the address family we will use */
	sa.sin_family = hp->h_addrtype ;
	/* zero means let UNIX choose a port -- temporary */
	sa.sin_port = 0 ;
	/**/

	/*
	 *	Get a socket to set up for them
	 */
	if((s = socket(hp->h_addrtype,SOCK_STREAM,pp->p_proto)) == ERRSOCKET)
		goto bad ;
	/* actually bind it to an address for everyone to see */
	if(bind(s,&sa,sizeof sa,0) < 0) goto bad ;
	return(s) ;
bad :
	return(ERRSOCKET) ;
}

-- 

	-Barry Shein, Software Tool & Die

There's nothing more terrifying to hardware vendors than
satisfied customers.

bvs@light.uucp (Bakul Shah) (05/07/89)

In article <53862@uunet.UU.NET> rick@uunet.UU.NET (Rick Adams) writes:
> [...]
>I can see it now:
>
>	getpwuid(213) becomes open("/dev/password/213")
>	gettimeofday() becomes open("/dev/clock")
>	etc.

This is not as silly as it seems.  In fact it can open up some
exciting possibilities.  Think of `open(<path>)' as a mapping
from a name space to object handles.  Once you get a handle, you
can invoke operations defined by that object.

A better idea is to have `obj_open(dir, path)', which takes a
directory handle + path and returns a handle.  A directory need
not be the familiar unix directory; it can be any object with a
function `lookup', which maps a name to an object.  Now we can
characterize obj_open with the following equalities:

    obj_open(dir, "foo") == dir->lookup(dir, "foo")
    obj_open(dir, "x/y/z") == obj_open(obj_open(dir, "x/y"), "z")
    obj_open(dir, "x/y/../z") == obj_open(dir, "x/z")

Now open can be defined in terms of obj_open:

    open("/foo") == obj_open(root, "foo")
    open("foo")  == obj_open(cwd, "foo")

And gettimeofday:

    gettimeofday(...) == open("/dev/clock")->read(...)

We can fix some obvious holes in this scheme and then extend it
to handle symbolic links, open options, adding new maps to a
directory etc.

>By your argument, we change everything to use open. (And if you
>think the kernel is big now, wait until you move most of the
>userlevel networking code into it)
>
>--rick

Not everything can use open but many of the major subsystems
can.  By doing so we make it easier to understand and extend
them.  New user level subsystems can be added if there is an
interface for registering new services and dispatching of
requests back to the user level objects.  This is preferable to
the current haphazard collection of library routines (which can
be built using this facility for compatibility).

As for the kernel, it can be made to *shrink* by moving things
out of it.  Once access permissions are checked for and a client
(caller of open) is hooked up to a server (object whose handle
is returned by open), the kernel has no business of being in the
middle.  I'd move almost everything out of it.

I don't think bsd4.3 or SVR3 can be transformed into something
like this without mega-hackery but perhaps a from-scratch
implementation of unix++ (using c++)....

-- Bakul Shah <..!{ames,sun,ucbvax,uunet}!amdcad!light!bvs>

dmr@alice.UUCP (05/07/89)

Buda's idea (378@chessene.UUCP) is to embed names of network services
into file names, so that

	open("/dev/hosts/uunet.uu.net/tcp/79", ...)

gets you to a TCP/IP connection to the named host on (I guess)
port 79.  It isn't so far-fetched as some would have it; indeed
we very nearly tried it in the Ninth Edition system in Bell Labs
research.

Some of the objections to it aren't relevant if you arrange things
correctly.  For example, the kernel need not know how to do the
connection dance; instead, the /dev/hosts directory is
virtual, served by a user-level program.  All the network connection
goo can be handled by this server, which returns the descriptor for
the completed connection.  Examples related to this approach are
described in several papers in the Portland Usenix conference
proceedings (Summer 1985).

However, we somewhat regretfully rejected schemes like Buda's
for several reasons.  First, each proposed embedding
began to get rather ornate.  There tend to be options, and different
networks have different naming structures.

Another thing that weighed heavily was that it was impossible to make
the /dev/host directory behave according to expectations one might
reasonably form.  For example, it is not possible to know all the hosts
in any non-trivial network, so what should you see if you list it?

Nevertheless, the idea could probably be pushed through.
(Indeed, as someone pointed out, it was done in Chaosnet.)
In particular, Rick Adams's reductions to absurdity are
quite close to things that the Plan 9 system (as opposed to
Ninth Edition) actually does; as many of its abstractions
as possible are mapped into the file system.

	Dennis Ritchie
	att!research!dmr
	dmr@research.att.com

rick@uunet.UU.NET (Rick Adams) (05/08/89)

> In particular, Rick Adams's reductions to absurdity are
> quite close to things that the Plan 9 system (as opposed to
> Ninth Edition) actually does; as many of its abstractions
> as possible are mapped into the file system.

Do they really spend 3 system calls to get the clock time
(open,read,close) or do they have some other scheme?

It seems like a hell of a lot of work to find out something simple
like the time of day. (Or am I still stuck in the past when
performance mattered?)

How far does plan 9 take the clock as a file analogy? Do they
reset the clock if root does a seek on it?

What about things like getpid or getppid?

--rick

pcg@aber-cs.UUCP (Piercarlo Grandi) (05/08/89)

In article <9321@alice.UUCP> dmr@alice.UUCP writes:

	[ on the idea of putting every type of object, e.g. TCP connections,
	networks, protocol suites in the file system, via portals or
	virtual filesystems ]
    
    Nevertheless, the idea could probably be pushed through.
    (Indeed, as someone pointed out, it was done in Chaosnet.)

It was also hinted in the original 4.2BSD design, which never got implemented,
for portals and user implemented domains and wrappers and ...

    In particular, Rick Adams's reductions to absurdity are
    quite close to things that the Plan 9 system (as opposed to
    Ninth Edition) actually does; as many of its abstractions
    as possible are mapped into the file system.

I vastly prefer the MUSS way of using as uniform referent the process rather
than the file like in Unix. MUSS defines an hideously efficient and well
designed IPC mechanism, and then everything is a process, including devices,
e.g. devices, ...; this is very powerful, as then you can substitute a process
for a device, or ... [ MUSS is described in SP&E, August 1979 ].

On some similar lines was Accent (now Mach), in which the uniform referent for
all kinds of object was the IPC port. Again, great flexibility, because behind
a port you could a process.

Hiding a process behind a file or filesystem or directory is less easy and
natural, I think.
-- 
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

les@chinet.chi.il.us (Leslie Mikesell) (05/09/89)

In article <9321@alice.UUCP> dmr@alice.UUCP writes:
>
>Nevertheless, the idea could probably be pushed through.
>(Indeed, as someone pointed out, it was done in Chaosnet.)
>In particular, Rick Adams's reductions to absurdity are
>quite close to things that the Plan 9 system (as opposed to
>Ninth Edition) actually does; as many of its abstractions
>as possible are mapped into the file system.

It makes sense to me.  Shouldn't the abstraction of relating a process
request to an OS resource be generalized as much as possible (and
we obviously already need open(), read(), write())?  Didn't someone
mention replacing gettimeofday() with open("/dev/clock")?  Consider
the advantage of being able to provide a single time source to a
network with a symlink instead of recompiling everything with the
gettimeofday() library routine.
What is needed to make this work (and worthwhile in its own right)
is a "parallel" fd that can be used for control requests.  That is,
read() or write() to that fd would do the things currently done via
fcntl() and ioctl().  This could be done in a text format, thus
converting the device-specific ioctl structs into something that we
already have to deal with: text lines of variable length.  This would
provide at once (a) the ability to fully control devices and file
locking from shell scripts or any language that knows read() and
write() - the device specific items can be read from a text file as
needed and (b) the ability to control devices over an network in a
machine-independent format since we already have the ability to write
character arrays among machines which would eliminate the problem with
ioctl() over RFS.
The obvious choice for the "parallel" fd would be -fd, but the
existence of fd 0 and the overloading of the "-" character on
command lines rules this out, so I suppose it would be fd|MAGIC_COOKIE.

Les Mikesell

roy@phri.UUCP (Roy Smith) (05/09/89)

In article <54270@uunet.UU.NET> rick@uunet.UU.NET (Rick Adams) writes:
> How far does plan 9 take the clock as a file analogy? Do they
> reset the clock if root does a seek on it?

	Seems to me that you should have to do a write to reset the clock.
Doing a seek should just change your time zone.
-- 
Roy Smith, System Administrator
Public Health Research Institute
{allegra,philabs,cmcl2,rutgers,hombre}!phri!roy -or- roy@phri.nyu.edu
"The connector is the network"

dpaulso@relay.nswc.navy.mil (05/10/89)

In article <54270@uunet.UU.NET> rick@uunet.UU.NET (Rick Adams) writes:
>> How far does plan 9 take the clock as a file analogy? Do they
>> reset the clock if root does a seek on it?

Then Roy Smith responds:
>	Seems to me that you should have to do a write to reset the clock.

yes.

>Doing a seek should just change your time zone.

nope.  seeking on the clock device would put you either into the past
or into the future, depending on the sign of the offset.

of course, only root would have permission to seek past EOF, which
would be a boon for those of us whose states have lotteries.

---
Dave Paulson	dpaulso@relay.nswc.navy.mil	(703)663-2137
"I've upped my standards; now up yours" -- Pat Paulsen

les@chinet.chi.il.us (Leslie Mikesell) (05/11/89)

In article <54270@uunet.UU.NET> rick@uunet.UU.NET (Rick Adams) writes:

>Do they really spend 3 system calls to get the clock time
>(open,read,close) or do they have some other scheme?

Do you open /dev/tty and close it every time you want to output a
character?

>It seems like a hell of a lot of work to find out something simple
>like the time of day. (Or am I still stuck in the past when
>performance mattered?)


With a scheme of providing an fd per resource, more standard fd's
could be defined and assumed to be inherited so the open/close
calls wouldn't have to be made.  Even without that, a process can
do the open() once and hang on to the fd.  The advantage is that
the connection is made at run-time and the actual service provided
could be modified by the requestor (by asking for a different named
resource) or the server (by re-mapping the request, perhaps to a
resource provided by another machine as in RFS files).

>How far does plan 9 take the clock as a file analogy? Do they
reset the clock if root does a seek on it?

A write would be the obvious thing.

>What about things like getpid or getppid?

Again, this would be great for networks - a single PID server could
make sure that pids where unique and allow them to be used in
lockfiles and such. 

Les Mikesell

john@frog.UUCP (John Woods) (05/11/89)

In article <12765@ut-emx.UUCP>, clyde@ut-emx.UUCP (Clyde W. Hoover) writes:
> Deja-vu!  In the old days when the ARPANET used NCP and the highest UNIX release
> was V6, (anyone remember 'smalldaemon' and 'largedaemon'?) a 
> version of the UIUC networking code worked much like that.
> Can you IMAGINE ... modifying namei to recognize "/dev/network" and not
> actually require all those files to exist?

Yes.  I can imagine that.  I can even go READ it.

MIT's CHAOSNET implementation for 2.9BSD used exactly the proposed scheme
(except that host IDs were octal numbers).  A set-uid device was treated by
namei() as the end of the pathname search, and the device open routine was
handed the remainder of the pathname string.

This migrated into UNOS (my fault, I'm afraid).  It actually turns out to
be quite useful for a number of things; for example, a proposal keeps floating
about to reduce the overloading of minor device numbers in our disk channel
interface by having the driver accept names like /dev/cc1/flop/dsqd9s512b
so that you can use any format that the floppy drive is capable of coping
with (and let's not even begin to discuss the 65536 unique SCSI target-IDs
that are potentially available).  We've not implemented this yet, since we
keep finding other ways to muddle through, but it would be handy.

Sort of a similar idea crops up in V[89] UNIX, courtesy of the file system
switch.  /proc is NOT a table of {filename, inum} pairs in a file somewhere;
the names are recognized by the lookup primitive of the /proc filesystem
handler.  Of course, getdents() on /dev/network might prove problematic... :-)

-- 
John Woods, Charles River Data Systems, Framingham MA, (508) 626-1101
...!decvax!frog!john, john@frog.UUCP, ...!mit-eddie!jfw, jfw@eddie.mit.edu

	Fellow cranks!!  ...I'm not ALONE!!

jc@minya.UUCP (John Chambers) (05/14/89)

In article <53862@uunet.UU.NET>, rick@uunet.UU.NET (Rick Adams) writes:
> > wrong with the open() call we have already?
> 
> You don't use the open() call because it doesnt fit well conceptually.
> Why not force EVERYTHING to use open().  I can see it now:
> 	getpwuid(213) becomes open("/dev/password/213")
> 	gettimeofday() becomes open("/dev/clock")
> 	etc.
> By your argument, we change everything to use open. (And if you
> think the kernel is big now, wait until you move most of the
> userlevel networking code into it)

These are silly, perhaps, but there's a reasonable argument for a version
of Unix that uses open() much more widely.  Imagine yourself trying to do
a security analysis of your kernel.  In earlier days, the only way a process
could gain access to anything that contains data was by calling open() or
exec(), and these both passed the name to namei().  This gave you a single
point at which all access permissions were checked.

Today, it's not so easy.  You also have to examine socket(), shmget(),
msgget(), semget(), and so on.  Each is a separate namespace for some
mechanism that accesses data, and each must be handled separately from
the others.  Each has different rules for access control.  This makes
the job much more difficult.  A building with only one door is easier
to secure than one with one door, four windows, a loading dock, and a
chimney.

It's not at all out of line to consider using ordinary file access-control
mechanisms for such things as shared-memory segments, semaphores, or TCP
sockets.  Thus, it'd be handy to be able to temporarily restrict, say,
telnet access to a system via a command like:
	chmod o-rw /dev/network/foo.bar/tcp/telnet
and have the presumably distributed version of namei() send a message to
a network server on foo.bar saying who I am and what I'm asking it to do.
From a user's viewpoint, this would certainly be convenient, since it is
the old, familiar way of doing things.  From a security analysts' viewpoint,
it would be a big win, since it invokes a common path through a network
access-control mechanism.

With the growth of such things as distributed banking, and the adoption 
of Unix as the industry-standard OS, security issues are becoming quite
an important issue.  Unfortunately, Unix is also growing into the sort
of security snafu that we see in other commercial OSs.  With a bit of
thought, we *could* have a version of Unix that has only a single path
for all access checks.

But I suppose this is too much to hope for.  It's not nearly complicated
enough for a real-world, commercial OS.  Sigh.


-- 
John Chambers <{adelie,ima,mit-eddie}!minya!{jc,root}> (617/484-6393)

[Any errors in the above are due to failures in the logic of the keyboard,
not in the fingers that did the typing.]

romain@pyramid.pyramid.com (Romain Kang) (05/15/89)

Does no one remember the Mail File System?  (Although some people have
hinted to me that it was intended as a outrageous joke.)

See the USENIX Association Summer Conference Proceedings, Atlanta 1986,
"A Mail File System for Eighth Edition UNIX", D. Hitz and P. Honeymman.

jc@minya.UUCP (John Chambers) (05/16/89)

In article <1989May6.133452.465@light.uucp>, bvs@light.uucp (Bakul Shah) writes:
> In article <53862@uunet.UU.NET> rick@uunet.UU.NET (Rick Adams) writes:
> > [...]
> >I can see it now:
> >
> >	gettimeofday() becomes open("/dev/clock")
> 
> This is not as silly as it seems.  In fact it can open up some
> exciting possibilities.  

Yeah, including the ability to make /dev/clock writable by a group, so that
you don't have to give the root password to everyone in your sys group.

Also, for some years, I've wondered why various kernel tables aren't files.
Rather than programs groveling around in /dev/kmem (and requiring them to
be setuid-root), wouldn't it be easier if they looked like:

crw-rw----   1 sys    sys    0, 37 Dec  6  1985 /dev/kernel/foo

Now no root permissions are needed to access this chunk of the kernel.
Given that Unix always has a device driver for accessing memory, think 
of how easy it would be to add all the tables as minor devices...

-- 
John Chambers <{adelie,ima,mit-eddie}!minya!{jc,root}> (617/484-6393)

[Any errors in the above are due to failures in the logic of the keyboard,
not in the fingers that did the typing.]