[net.unix-wizards] Is this a pipe, fstat

jlm@stl.UUCP (John Messenger) (02/27/85)

[4.2 BSD VAX 750 - you know, the one that gives mc tbuf par fault panics]

Friends,
When is a descriptor a pipe, and when is it a file?  I have programs
which read (for instance) stdin, and want to know whether they are dealing
with a pipe or not.  One way to do this is to attempt a seek, and see
if you get an error.  However, using the following program:

#include <errno.h>
main() { if (lseek(0,1,1) < 0) perror("lseek"); }
I get:
a.out
	(nothing - all ok)
a.out < a.out
	(nothing - all ok)
cat a.out | a.out
	lseek: Invalid argument (that is, EINVAL)

where I would expect to get lseek: Invalid seek (that is, ESPIPE).

What I really need of course is something that tells me what my
descriptor describes.  Why doesn't fstat() do this?  My manual says
that fstat() on a pipe reports an ordinary file with an i-node number,
restricted permissions, and a not necessarily meaningful length.
Should it really do such a (seemingly perverse) thing?

Seeking *forward* on pipes seems to me a reasonable thing to do.  What
is the general opinion on this?

Sorry if this is another of the "perennial" topics that have been well
dealt with before - I'm hoping it will stand another airing for the
benefit of us "newcomers".
----------------------------------------------------------------------
John Messenger - mcvax!ukc!stl!jlm.

guy@rlgvax.UUCP (Guy Harris) (02/28/85)

> [4.2 BSD VAX 750 - you know, the one that gives mc tbuf par fault panics]

I think that's a known bug - there was some problem with it looking at
the low-order bit of the error code, which may have caused that problem.

> However, using the following program:
> 
> #include <errno.h>
> main() { if (lseek(0,1,1) < 0) perror("lseek"); }
> I get:
> cat a.out | a.out
> 	lseek: Invalid argument (that is, EINVAL)
> 
> where I would expect to get lseek: Invalid seek (that is, ESPIPE).

Most of the rest of us would expect it, too; in fact, we changed it to
return ESPIPE.  Returning EINVAL brings no benefits that I can think of.
It's a trivial fix.

> What I really need of course is something that tells me what my
> descriptor describes.  Why doesn't fstat() do this?  My manual says
> that fstat() on a pipe reports an ordinary file with an i-node number,
> restricted permissions, and a not necessarily meaningful length.
> Should it really do such a (seemingly perverse) thing?

The manual lies.  It later says, under BUGS, "Applying 'fstat' to a socket
returns a zero'd (sic) buffer."  It leaves it up to the reader to figure
out that since pipes in 4.2 are implemented as sockets, it reports a bunch
of zeroes rather than the aforementioned ordinary file.

In V7 and 4.1BSD, pipes *were* implemented as slightly funny files, as
such, reporting that sort of information wasn't too perverse.  The length,
in some versions, was the number of bytes queued up in the pipe.  In System
III/V, they're implemented as funnier files of type S_IFIFO; you can create
inodes of that type with directory entries pointing to them, open them
for reading and writing, and thus set up pipelines connecting non-ancestrally-
related processes.  There, too, the length is the number of bytes queued
in the pipe.

We put in named pipes, and fiddled them to return semi-meaningful data
on an "fstat".  We use an inode (for unnamed pipes, an inode that resides
in core but not on disk - I have other plans for that kind of inode for
making "creat"ing a file, writing to it, and closing it an atomic operation,
so those in-core inodes aren't just a kludge for pipes) as the glue to hold
together a read-socket and a write-socket.  The trouble is that S3/S5 "fifo"s
permit a process to send data down a read/write file descriptor and then read
the same data from the same descriptor.  *Somebody* out there might use it,
so we support it.

This required a lot of ugly ripping of the pipe code.  FIFOs are a nasty kludge.
The only thing you can say about them is that they are better than not having
any way of permitting non-ancestrally-related processes from communicating,
except by using files as mailboxes and signals as a block/wakeup mechanism
(the standard V6/V7/S[35] signal mechanism, used for this purpose,
*will* eventually blow your program away - it's only a matter of time).

> Seeking *forward* on pipes seems to me a reasonable thing to do.  What
> is the general opinion on this?

It might be nice, but it'd be a royal pain to implement.  First of all,
some seeks just wouldn't work.  "lseek(pipefd, xxx, 2)" can't be done -
it requires you to predict when the guy on the other end of the pipe
is going to stop writing.  The other two flavors are sort of doable,
but you'd have to keep track of how much data had been written to the pipe
*and* how much data was being skipped past.  You'd throw data away until
the current seek point was reached.  (Of course, with two readers this
would lose, but two readers on a pipe just *can't* have the same semantics
as two readers on a file, because they can't read the same data.)
However, it's not clear that this would buy you anything for all the work
it takes.  True random access to a pipe is impossible, and that's the major
use of "lseek".  Using it to flush data might be nice, but you can do that
in the user program.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

jbn@wdl1.UUCP (03/05/85)

     A new device for implementing login security has just been introduced by
Gordian System, Inc.  (3512 West Bayshore Road, Palo Alto, CA  94303,
415-494-8414).  They offer an IFF (identify-friend-foe) type device.  This
is not a new idea, but Gordian is the first to build a really cheap one.  They
make a gadget about the size and shape of a domino, which contains a 6 digit
LCD display, a photocell, a microprocessor, and a battery.  When logging in,
the user gets the message ``Hold your key up to the flashing area below
until the key continuously displays a password''.  The key READS BAR CODE
from the user's terminal, runs the data through an algorithm in the user's
hand-held key device, and displays a number.  The user types in the number
and if the number is accepted is then logged in.
     This thing is about $50 in quantity 100, and drops to $10 or so in large
(thousands) quantities.  For $15,000, you get 100 keys, a ``key-cutting''
machine, host software (in source form) and technical assistance setting the
security system up.  No extra charge for multiple hosts using the same host
software; they make their money on the keys.
     I haven't actually seen this yet, but the salesman wants to come over
and show it to me.  I don't know how good the algorithms are from a security
standpoint, but the basic concept is sound in theory.

					John Nagle