On Fri, Mar 24, 2017 at 4:06 AM, shawn wilson <ag4ve.us@gmail.com> wrote:
I actually have strong opinions about this (read: disagreements). Your
shell shouldn't know about connect() - I guess allowing writing to
/dev/eth0 would work for me. But in bash, IIRC that damn ghost file
thing is like half of the files in source and it helps nothing. Maybe
if the point was to allow some remote shell (like X does) I could see
it (but than I'd scream about the security implications about
something like that). And I'll say again - why? You want a socket -
nc, ncat, socat - pick one - don't abuse your shell.

You're right; your shell should not know about connect(). But the argument isn't that it should; the argument is that connect() itself is superfluous.

Perhaps a way to focus the discussion would be to explain how networking works in the Plan 9 world (which is where at least Ron is coming from...unless he corrects me).

In Unix everything is a file, but the limitations of that model become apparent pretty quickly:
-For things that require some sort of control plane, one ends up with ioctl() or something like it.
-Traditionally Unix required that these files exist in the directory structure resident on the disk filesystem, hence major/minor device numbers and file types.
-Sockets didn't fit exactly into that model so they got a whole slew of special-purpose system calls.
-That seemed to open the flood gates to a number of other, similar special-purpose interfaces (POSIX termios? To be fair, these [and sockets!] were predated by s/gtty etc).

All of these are non-orthogonal: they cannot be easily combined or reused. Little binary data structures shared between the kernel and the rest of the world, accessed by special system calls and interpreted by arcane user-space programs, are the order of the day; one had better hope that the structure definitions are synchronized between building the kernel and the tools or hilarity ensues. Since it's all binary, one has to deal with byte ordering issues and type widths and so forth if one wants to share these things over a network. The interface between the kernel and userspace is very wide.

However, this has been "normal" since at least the 1980s so no one really thinks twice about it.

By contrast in Plan 9, everything is sort of a small *filesystem* and there exist (unprivileged) primitives for mapping these filesystems into a process's view of the file namespace and manipulating them into various configurations. Often, these files are synthesized on demand by a device driver or user-space process; there is no disk-resident copy of the names. For networking, there is no /dev/eth0 file, but there are /net/ether0 and /net/tcp *directories*.

If I want, say, to make a TCP connection I open a file (/net/tcp/clone) and read from it. These operations cause a new directory representing that connection to spring into existence; that directory contains two files: /net/tcp/$n$/ctl and /net/tcp/$n$/data (actually, the file descriptor returned by opening /net/tcp/clone corresponds to /net/tcp/$n$/ctl, but that's a detail). I write a string describing the port and address I wish to connect to into the ctl file and attempt to open the data file; when that returns successfully, I have an established connection and I read/write the corresponding file descriptor to exchange data with the remote system. I can further control the connection via writes of special messages into the ctl file. Of course, the details of connection establishment are abstracted away into a convenient library interface so I don't really think about it for work-a-day programming, but I can also do this little dance with e.g. cat and echo, so I can do the same from the shell if I like. Why bother with nc, netcat, socat, etc when just plain cat will do?

Since all of the details of actually manipulating network connections and so forth are hidden behind this nice filesystem-based interface, neither the shell nor the tools have to know or care that they're dealing with a network. The control plane is handled via this `ctl` thing, which is far superior to ioctl() in that the messages accepted by the ctl file are text, not little binary integers and pointers. Since everything is text based, I can share these filesystems over a network and manipulate them from remote machines (e.g., I can import the TCP/IP stack from another machine and use it to make connections: all with no programming whatsoever). The kernel interface is elegant, simple, relatively narrow and highly orthogonal.

Of course, it has its downsides: sometimes it certainly DOES feel like the "if all you have is a hammer..." thing and one finds tiny parsers for the DSLs implemented by various ctl files and things all over the place and for connectionless protocols like UDP one has to (wait for it...) prepend or parse a binary header at the beginning of the data when writing/reading a packet. For UDP this is simple enough, but clearly it shows a general weakness in the model. It's also hard to do scatter/gather I/O. Because things are based on open/read|write/close, lots of things are stateful that don't have to be on e.g. Unix. Plan 9 relies heavily on convention (e.g., all the tools expect the network to be mounted at /net, but there's no one with a golden hammer standing over you forcing you to put it there. You could mount it on /foobar if you wanted...but then nothing would work); the implementation is buggy and many would argue quirky; it's slow; most importantly, it's incompatible with the rest of the world and requires you to dump your old toolset and adopt the Plan 9 Way to be productive. Like Lisp, it's great for stretching your mind but perhaps not so much for solving real-life problems. However, I often feel that when one tries to explain it to folks who haven't seen it, the explanations fall flat because folks look at them with too many of their preconceptions based on how Unix and Linux work. It's a very different model and a lot of folks with experience on the research systems would argue that it is philosophically more Unix-like than Unix (including Linux) these days.

        - Dan C.