Hi all,
I was reading a recent thread, over on the FreeBSD forums about groups that quickly devolved into a discussion on the origin of the operator group:
https://forums.freebsd.org/threads/groups-overview.82303/
I thought y’all would be the best place to ask the questions that arose in me during my read of the thread.
Here they are in no special order:
1. Where did operator come from and what was it intended to solve?
2. How has it evolved.
3. What’s a good place to look/ref to read about groups, generally?
I liked one respondent’s answer about using find, heir, and the files themselves to learn about groups being used in a running system, paying attention to the owner, Audi, etc along the way and this is how I do it now, but this approach doesn’t account for the history and evolution.
Thanks!
Willu
Sent from my iPhone
Greg wrote:
> I guess pipe(2) kind of started this mess, [...] Maybe I'm
> going to far with thinking pipe() could/should have just been a library
> call that used open(2) internally, perhaps connecting the descriptors by
> opening some kind of "cloning" device in the filesystem.
At times I’ve been pondering this as well. All of creat/open/pipe could have been rolled into just open(). It is not clear to me why this synthesis did not happen around the time of 7th edition; although it seems the creat/open merger happened in BSD around that time.
As to pipe(), the very first implementation returned just a single fd where writes echoed to reads. It was backed by a single disk buffer, so could only hold ~500 bytes, which was probably not enough in practice. Then it was reimplemented using an anonymous file as backing store and got the modern two fd system call. The latter probably arose as a convenient hack to store the two file pointers needed.
It would have been possible to implement the anonymous file solution still using a single fd, and storing the second file pointer in the inode. Maybe this felt as a worse hack at the time (the conceptual split in vnode / inode was still a decade into the future.)
With a single fd, it would also have been possible to have a cloning device for pipe’s as you suggest (e.g. /dev/pipe, somewhat analogous to the implementation of /dev/stdin in 10th edition). Arguably, in total code/data size this would not have been much different from pipe().
My guess is that from a 1975 perspective, creat/open/pipe was not perceived as something that needed fixing.
Dan wrote:
> 3BSD and I think 4.1BSD had vread() and vwrite(), which looked like
> regular read() and write() but accessed pages only on demand. I was a
> grad student at Berkeley at the time and remember their genesis. Bill
> and I were eating lunch from Top Dog on the Etcheverry Hall plaza, and
> were talking about memory-mapped I/O. I remember suggesting the actual
> names, perhaps as a parallel to vfork(). I had used both TENEX and
> Multics, which both had page mapping. Multics' memory-mapped segments
> were quite fundamental, of course. I think we were looking for something
> vaguely upward compatible from the existing system calls. We did not
> leap to an mmap() right away just because it would have been a more
> radical shift than continuing the stream orientation of UNIX. I did not
> implement any of this: it was just a brainstorming session.
Thank you for reminding me of these.
On a substrate with a unified buffer cache and copy-on-write, vread/vwrite would have been very close to regular read/write and maybe could have been subsumed into them, using flags to open() as the differentiator. The user discernible effect would have been the alignment requirement on the buffer argument.
John Reiser wrote that he "fretted” over adding a 6 argument system call. Perhaps he was considering something like the above as the alternative, I never asked.
I looked at the archives and vread/vwrite were introduced with 3BSD, present in 4BSD but marked deprecated, and absent from 4.1BSD. This short lifetime suggests that using vread and vwrite wasn’t entirely satisfactory in 1980/81 practice. Maybe the issue was that there was no good way to deallocate the buffer after use.
Hello,
I've recently started to implement a set of helper functions and
procedures for parsing Unix-like command-line interfaces (i.e., POSIX +
GNU-style long options, in this case) in Ada.
While doing that, I learned that there is a better way to approach
this problem – beyond using getopt(s) (which never really made sense to
me) and having to write case statements in loops every time: Define a
grammar, let a pre-built parser do the work, and have the parser
provide the results to the program.
Now, defining such a grammar requires a thoroughly systematic approach
to the design of command-line interfaces. One problem with that is
whether that grammar should allow for sub-commands. And that leads to
the question of how task-specific tool sets should be designed. These
seem to be a relatively new phenomenon in Unix-like systems that POSIX
doesn't say anything about, as far as I can see.
So, I've prepared a bit of a write-up, pondering on the pros and cons
of two different ways of having task-specific tool sets
(non-hierarchical command sets vs. sub-commands) that is available at
https://www.msiism.org/files/doc/unix-like_command-line_interfaces.html
I tend to think the sub-command approach is better. But I'm neither a UI
nor a Unix expert and have no formal training in computer things. So, I
thought this would be a good place to ask for comment (and get some
historical perspective).
This is all just my pro-hobbyist attempt to make some people's lives
easier, especially mine. I mean, currently, the "Unix" command line is
quite a zoo, and not in a positive sense. Also, the number of
well-thought-out command-line interfaces doesn't seem to be a growing
one. But I guess that could be changed by providing truly easy ways to
make good interfaces.
--
Michael
> one other thing that SLS breaks, for data files, is the whole Unix 'pipe'
> abstraction, which is at the heart of the whole Unix tools paradigm.
Multics had an IO system with an inherent notion of redirectable data
streams. Pipes could have--and eventually did (circa 1987)--fit into
that framework. I presume a pipe DIM (device interface manager)
was not hard to build once it was proposed and accepted.
Doug
> From: Larry McVoy
> If you read(2) a page and mmap()ed it and then did a write(2) to the
> page, the mapped page is the same physical memory as the write()ed
> page. Zero coherency issues.
Now I'm confused; read() and write() semantically include a copy operation
(so there are then two copies of that data chunk, and possible consistency
issues between them), and the copied item is not necessarily page-sized (so
you can't ensure consistency between the original+copy by mapping it in). So
when one does a read(file, &buffer, 1), one gets a _copy of just that byte_
in the process' address space (and similar for write()).
Yes, there's no coherency issue between the contents of an mmap()'d page, and
the system's idea of what's in that page of the file, but that's a
_different_ coherency issue.
Or am I confused?
PS:
> From: "Greg A. Woods"
> I now struggle with liking the the Unix concept of "everything is a
> file" -- especially with respect to actual data files. Multics also got
> it right to use single-level storage -- that's the right abstraction
Oh, one other thing that SLS breaks, for data files, is the whole Unix 'pipe'
abstraction, which is at the heart of the whole Unix tools paradigm. So no
more 'cmd | wc' et al. And since SLS doesn't have the 'make a copy'
semantics of pipe output, it would be hard to trivially work around it.
Yes, one could build up a similar framework, but each command would have to
specify an input file and an output file (no more 'standard in' and 'out'),
and then the command interpreter would have to i) take command A's output file
and feed it to command B, and ii) delete A's output file when the whole works
was done. Yes, the user could do it manually, but compare:
cmd aaa | wc
and
cmd aaa bbb
wc bbb
rm bbb
If bbb is huge, one might run out of room, but with today's 'light my cigar
with disk blocks' life, not a problem - but it would involve more disk
traffic, as bbb would have to be written out in its entirety, not just have a
mall piece kept in the disk cache as with a pipe.
Noel
> From: "Greg A. Woods"
> the elegance of fork() is incredible!
That's because in PDP-11 Unix, they didn't have the _room_ to create a huge
mess. Try reading the exec() code in V6 or so.
(I'm in a bit of a foul mood today; my laptop sorta locked up when a _single_
Edge browser window process grew to almost _2GB_ in size. Are you effing
kidding me? If I had any idea what today would look like, back when I was 20 -
especially the massive excrement pile that the Internet has turned into - I
never would have gone into computers - cabinetwork, or something, would have
been an infinitely superior career choice.)
> I now struggle with liking the the Unix concept of "everything is a
> file" -- especially with respect to actual data files. Multics also got
> it right to use single-level storage -- that's the right abstraction
Well, files a la Unix, instead of the SLS, are OK for a _lot_ of data storage
- pretty much everything except less-common cases like concurrent access to a
shared database, etc.
Where the SLS really shines is _code_ - being able to just do a subroutine
call to interact with something else has incredible bang/buck ratio - although
I concede doing it all securely is hard (although they did make a lot of
progress there).
Noel
>> > It's part of my academic project to work on provable compiler security.
>> > I tried to do it according to the "Reflections on Trusting Trust" by Ken
>> > Thompson, not only to show a compiler Trojan horse but also to prove that
>> > we can discover it.
>>
>> Of course it can be discovered if you look for it. What was impressive about
>> the folks who got Thompson's compiler at PWB is that they found the horse
>> even though they weren't looking for it.
> I had not heard this story. Can you elaborate, please? My impression from having
> read the paper (a long time ago now) is that Ken did the experiment locally only.
Ken did it locally, but a vigilant person at PWB noticed there was an
experimental
compiler on the research machine and grabbed it. While they weren't looking for
hidden stuff, they probably were trying to find what was new in the
compiler. Ken
may know details about what they had in the way of source and binary.
Doug
> It's part of my academic project to work on provable compiler security.
> I tried to do it according to the "Reflections on Trusting Trust" by Ken
> Thompson, not only to show a compiler Trojan horse but also to prove that
> we can discover it.
Of course it can be discovered if you look for it. What was impressive about
the folks who got Thompson's compiler at PWB is that they found the horse
even though they weren't looking for it.
Then there was the first time Jim Reeds and I turned on integrity control in
IX, our multilevel-security version of Research Unix. When it reported
a security
violation during startup we were sure it was a bug. But no, it had snagged Tom
Duff's virus in the act of replication. It surprised Tom as much as it did us,
because he thought he'd eradicated it.
Doug