I've assembled some notes from old manuals and other sources
on the formats used for on-disk file systems through the
Additional notes, comments on style, and whatnot are welcome.
(It may be sensible to send anything in the last two categories
directly to me, rather than to the whole list.)
Back when it was all UUCP, a friend setup his own system, bang.
He then used his initials as his login, bam.
So when asked for his email address he answered
bang bang bang bam
Bret was a funny guy.
Gerard Holzmann took the true and false commands as
the jumping-off point for "Code Inflation", an
installment of his "Reliable Code" blog and column
in IEE Software. An informative, but depressing, read:
The existence of cd as a real command is a bit silly (Ubuntu doesn't
seem to bother with it), but it is technically required by the standard.
Just for the record, Fedora 21 supplies /bin/cd, as part
of package bash-4.3.42-1. Interestingly, it is a shell
lu$ cat /bin/cd
builtin cd "$@"
As has been said here, it's hard to see the functional point.
Others have remarked on the continued life of /bin/true and
/bin/false. There are some who use those as shells in /etc/passwd
for logins that should never actually be allowed to do anything
directly. I have no strong personal feeling about that, I'm just
And to be fair (as has also already been displayed here), the
copyright notice inserted in the once-empty /bin/true was hundreds
of bytes long, not thousands. Let us call out silliness, but let
us not make it out as any sillier than it actually is.
UNIX old fart and amateur pedant
Seen on another list... And I got quoted by Steve Bellovin :-)
Dave Horsfall DTM (VK2KFU) "Those who don't understand security will suffer."
---------- Forwarded message ----------
From: Kent Borg
Subject: Re: [Cryptography]
"NSA-linked Cisco exploit poses bigger threat than previously thought"
On 08/25/2016 06:06 PM, Steven M. Bellovin wrote:
> I first heard more or less that line from Doug McIlroy himself; he
> called C the best assembler language he'd ever used.
Ancient fun-fact: Years ago there was an article in Byte magazine
describing how a useful subset of C could be directly assembled into 68000
code. Not compiled, assembled.
C is a stunning assembly language. When those wild-eyed nerds at AT&T
decided to write Unix not in assembly but in C (where was management!?),
it was radical. But C was up to (down to?) the task, it was pioneering
then and is still doing useful things decades later: From the fastest
supercomputers to some pretty slim microcontrollers (plus a hell of a lot
of Android devices) multitudes of computers run a Linux kernel compiled
from the *same* C source code, with almost no assembly. Big-endian,
little-endian: no matter. Different word lengths: no matter.
That is one impressive cross-platform assembly language!
Unfortunately, C is also a dangerous language that mortal programmers
cannot reliably wield.
-kb, the Kent who knows he is pressing his luck on a moderated
cryptography mailing list, but C deserves a lot of respect, as it also
deserves to be efficiently sent into a dignified retirement.
The cryptography mailing list
The latest issue of the IEEE Annals of Computing was published
electronically today, and it has an article that I expect many
TUHS list readers will enjoy reading:
Notes on the History of Fork and Join
- Nelson H. F. Beebe Tel: +1 801 581 5254 -
- University of Utah FAX: +1 801 581 4148 -
- Department of Mathematics, 110 LCB Internet e-mail: beebe(a)math.utah.edu -
- 155 S 1400 E RM 233 beebe(a)acm.org beebe(a)computer.org -
- Salt Lake City, UT 84112-0090, USA URL: http://www.math.utah.edu/~beebe/ -
All, sorry this is slightly off-topic. I'm trying to
find out what fstat(2) returns when the file descriptor
is a pipe. The POSIX/Open Group documentation doesn't
really specify what should be returned. Does anybody have
P.S. Why? xv6 has fstat() but returns an error if the
file descriptor isn't associated with an i-node. I'm
trying to work out if/how to fix it.
I remember once, long ago--probably in the early 1980s--writing
a program that expected fstat on a pipe to return the amount of
data buffered in the pipe. It worked on the system on which
I wrote the code. Then I tried it on another, related but
different UNIX, and it didn't work. So if POSIX/SUS don't
prescribe a standard, I don't think one should pretend there
is one, and (as I learned back then) it's unwise to depend
on the result, except I think it's fair not to expect fstat
to fail on any valid file descriptor.
I'm pretty sure that in 7/e and earlier, fstat on a pipe
reported a regular file with zero links. There was a reason
for this: the kernel in fact allocated an i-node from a
designated pipe device (pipedev) file system, usually the
root. So the excuse that `there's no i-node' was just wrong.
In last-generation Research systems, when pipes were streams
(and en passant became full duplex, which caused no trouble
at all but simplified life elsewhere--I think I was the one
who realized that meant we didn't need pseudo-ttys any more),
the system allocated a pair of in-core i-nodes when a pipe
was created. As long as such an i-node cannot be accidentally
confused with one belonging to any disk file system, this
causes no trouble at all, and since it is possible to have
more than one disk file system this is trivially possible
just by reserving a device number. (In fact by then our
in-core i-nodes were marked with a file system type as well,
and pipes just became their own file system.) stat always
returned size 0 for (Research) stream pipes, partly because
nobody cared enough, partly because the implementation of
streams didn't keep an exact count of all the buffered data
all along the stream, just a rough one sufficient for flow
control. Besides, with a full-duplex pipe, which direction's
data should be counted?
Returning to the original question, I'd suggest that:
-- fstat(fd) where fd is a pipe should succeed
-- the file should be reported to have zero links,
since that is the case for a pipe (unless a named pipe,
but if you support those you probably have something
else to stat anyway)
-- the file type should be IFIFO if that type exists
in xv6 (which it wouldn't were it a real emulation of
6/e, but I gather that's not the goal), IFREG otherwise
-- permissions probably don't matter much, but for
sanity's sake should be some reasonable constant.
> From: Warren Toomey
> xv6 is a Unix-like OS written for teaching purposes.
I'm fairly well-aware of Xv6; I too am planning to use it in a project.
But back to the original topic, it sounds like there's a huge amount of
variance in the semantics of doing fstat() on a pipe. V6 doesn't special-case
it in any way, but it sounds as if other systems do.
What V6 does (to complete the list) is grow the temporary file being used to
buffer the pipe contents up to a certain maximum size, whereupon it halts the
writer, and waits for the reader to catch up - at which point it truncates
the file, and adjusts the read and write pointers back to 0. So fstat() on
V6, which doesn't special-case pipes in any way for fstat(), apparently
returns 'waiting_to_be_read' plus 'already_read'.
>>> xv6 has fstat() but returns an error if the file descriptor isn't
>>> associated with an i-node.
>> ?? All pipe file descriptors should have an inode?
To answer my own question, after a quick look at the Xv6 sources (on my
desktop ;-); it turns out that Xv6 handles pipes completely differently;
instead of borrowing an inode, they have special 'pipe' structures. Hence the
error return in fstat() on Xv6. (That difference also limits the amount of
buffered data in a pipe to 512 bytes. So don't expect high throughput from a
pipe on Xv6! :-)
So I guess you get to pick which semantics you want fstat() on a pipe to have
there: V6's, V7's (see below), or something else! :-)
> 7th Ed seems to return the amount of free space in the pipe, if I read
> the code correctly:
I'm not sure of that (see below), but I think it would make more sense to
return the amount of un-read data (which is what I think it does do), as the
closest semantics to fstat() on a file.
It might also make sense to return the amount of free space (to a writer), and
the amount of data available to read (to a reader), since those are the
numbers users will care about. (Although then fstat() on the write side of a
pipe will have semantics which are inconsistent with fstat() on files. And if
the user code knows the maximum amount of buffering in a pipe, it could work
out the available write space from that, and the amount currently un-read.)
> /* Call stat1() with the current offset in the pipe */
> stat1(fp->f_inode, uap->sb, fp->f_flag&FPIPE? fp->f_un.f_offset: 0);
> ds.st_size = ip->i_size - pipeadj;
I'm too lazy to go read the code (even though I already have it :-), but V7
seems to usually be very similar to V6. So, what I suspect this code does is
pass the expression:
((fp->f_flag & FPIPE) ? fp->f_un.f_offset : 0)
as 'pipeadj' (to account for the amount that's already been read), and then
returns (ip->i_size - pipeadj), i.e. the amount remaining un-read, as the
> From: Warren Toomey
> I'm trying to find out what fstat(2) returns when the file descriptor
> is a pipe.
In V6, it returns information about the file (inode) used as a temporary
storage area for data which has been written into the pipe, but not yet read;
i.e. it's an un-named file with a length which varies between 0 and 4KB.
> xv6 has fstat() but returns an error if the file descriptor isn't
> associated with an i-node.
?? All pipe file descriptors should have an inode?