Subject: Re: cat(1) question: multiple "-"s
To: Johnny Billquist <bqt@update.uu.se>
From: Steven M. Bellovin <smb@cs.columbia.edu>
List: netbsd-users
Date: 04/18/2006 14:26:18
On Tue, 18 Apr 2006 20:07:29 +0200, Johnny Billquist <bqt@update.uu.se>
wrote:
> Steven M. Bellovin wrote:
> > If we had streams, and if pipes were streams, it could be done quite
> > easily -- make sure there's a 0-length record present. Otherwise, it's
> > not particularly easy. It would take a kernel multiplexor that you handed
> > several files -- more likely, several file descriptors -- that would read
> > the first until it ended, give EOF, then the next, etc.
>
> Well, it also needs to signal eof at the end of each file, and then
> reset the status if another file exists, which to switch over to.
That's what I said, I think.
>
> But I'm not sure about your thoughs... You need read() to return 0. I
> don't think a stream have the data stored in records. A stream will
> return as much data as exists, or until the read buffer is full. If no
> data exists, it will wait. It will only return 0 on a EOF situation.
> That's what we want to access. I suspect this means that we need some
> oob data to tell that en EOF should be delivered here, or the
> implementation behind the read needs to be changed.
> The whole point of a stream is that there isn't any structure to it,
> which includes the absence of a record concept.
>
> But I might be wrong. It's been a long time since I was anywhere near
> that kind of code (back in 4.3BSD...).
>
> A pipe can be wrapped in a stream, by the way, can it not? A stream is
> just distinguished by the fact that it have a FILE descriptor. When
> stdin is redirected to a pipe, it's still a stream?
> Or am I confusing things a lot now?
>
We may be talking past each other. I'm speaking of System V Release 4
streams and/or Ritchie streams. Both were capable of preserving record
boundaries.
Without going into details, streams a form of kernel pipeline. You had
producers and consumers, but you also had filters. Thus, a tty device
would simply generate an uinterpreted byte stream; if you wanted tty
semantics such as erase and kill, you pushed a line discipline on top of
the tty fd. But the same could be done with TCP fds and pipe fds -- no
need for ptys in that model. (I'm oversimplifying.)
Ritchie streams contained a linear sequence of buffers of some maximum
length. There were also control records; one was record mark, which (for
example) the tty line discipline would emit when it saw a ^D. SVR4
streams were more like mbuf chains, in that each stream message could be
the head of a list of buffers. In this case, a 0-length buffer list
indicated a record mark.
We're getting off-topic, but I think it's clear how either scheme would
let you DTRT for this case.
--Steven M. Bellovin, http://www.cs.columbia.edu/~smb