[comp.unix.questions] System V manuals

guy%gorodish@Sun.COM (Guy Harris) (10/09/87)

> Haven't seen the book you cite anywhere. All the bookstores around here
> have the SVID-based one only.

Well, that's too bad, but the book *you* cite appears to be the only book that
claims to be a System V manual (as opposed to a System V interface definition)
and that has this layout.  In other words, the book you cite is an exception to
the rule, and complaints about its contents cannot validly be extended to
complaints about System V documentation in general.

> I wish it was. Unfortunately the book I cite is the only one I've seen,
> and it's also the one Microport is distributing as their UNIX manual.

It's not the one AT&T is distributing as *its* UNIX manual, nor is it, I
suspect, what most vendors distribute.

> I didn't say it was in section 2 or section 3. I said it was in BA_SYS...

I quote here from your original article:

> Except that the O/S *manuals* follow the SVID. And except that it confuses
> people. "Hey, peter, how come they have read and fread?" "Well, fread is
> a library routine." "Oh. How do you tell which ones are library routines?"
> "read the manual. Library routines are section 3" "section 3? I don't
> have a section 3" "What? Let me look at that... they must be kidding".

I see nothing about BA_SYS here.  I see only a claim that "the O/S manuals
follow the SVID", which is NOT true in general; it is only true for that one
anomalous manual you saw.  All the System V manuals we've gotten from AT&T have
the traditional division between sections 2 and 3.

> > Remember, we're NOT just talking about "traditional UNIX systems" here.
> > This "read" could be implemented atop a non-UNIX system, or a UNIX system
> > with more general facilities for sharing than "traditional" systems.
> 
> Since the title of the message is "System V manuals", don't you think we
> should be talking about System V?

Well, first of all, if we're talking about System V, we should talk about it in
comp.unix.questions, so this discussion is moving there.

Second of all, in the claim you made said nothing about implementing "read"
under a vanilla System V system.  You just said

> I don't believe you could implement "read" as a library routine and retain
> the attribute of leaving the file descriptor at the point last read, unless
> you were to "implement" it by making a direct call to the existing read
> routine. Certainly buffering would be out.

with no such qualification.  You could definitely do this under some
non-vanilla implementations, e.g. Apollo's DOMAIN/IX.

For that matter, you could probably do it under vanilla System V, if the IPC
code, including shared memory, is configured into the kernel.  You may not
*want* to do it that way, but it's not impossible.

The fact that it *doesn't* happen to be implemented that way in most UNIX
systems is irrelevant; you didn't say it *wasn't* done that way, you said that
you didn't believe it *could* be done that way.
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com

guy%gorodish@Sun.COM (Guy Harris) (10/16/87)

> > Why does the SVID stick read() and fread() in the same place?
> 
> I don't know about your system, but on mine you need to supply
> an int to read and a pointer to type FILE [ FILE *fn etc]

Which doesn't answer the question.  I have no idea why they were stuck in the
same place; it certainly doesn't reflect the way this stuff is actually
packaged.  If there is some notion that the stuff in BA_OS should represent
"system calls" (whatever that means - on *some* systems it means "routines
consisting of a tiny wrapper around a trap", but not on others), "fread" - and
"fopen", which is also in BA_OS - certainly doesn't belong there; I know of no
UNIX implementations where "fopen" and/or "fread" are just simple traps.

> The difference is that read() and its brethren use file
> to do all there opperations while fread() and it's brethren use
> streams.
> 
> Apearently every stream has at least one file handle assoicated with it
> but the level and method that streams interact with the kernel
> are quite different than simple files.  That is "any Transport
> Level Interface" [network, etc.] MUST be a stream when you open
> it.  If you want to then use read() against it you must manually
> push a streams-module that will properly react to the read()
> calls.

Unfortunately, the word "stream" is vastly overused when discussing computer
systems, and in particular when discussing UNIX systems.  "stream" is used to
refer to the object that a standard I/O "FILE *" refers to; it is also used to
refer to the object to which a UNIX file descriptor created by opening a
STREAMS device refers.  The two meanings have little to do with one another.  A
standard I/O "stream" can have as its file descriptor a STREAMS "stream", but
it need not, nor need you wrap a standard I/O "stream" around a UNIX "stream".

> I guess what I am trying to say is that, on my system of corse,
> read() and fread() have a different scope.  It is therefore
> approprate that they are listed as read(2) and fread(3S).
> If your system is not "UNIX" read may end up as a library
> refrence, but if it is a library on you computer I don't
> think it's standard.  On the other hand, an "fread" type
> of system-call-primitive is NECESSARY to interact with the
> streams modules in the kernel.  Since SVID includes streams
> definitions, I would assume that fread(2) will soon be the
> new standard, hence SVID may well say read(2) and fread(2)
> [or however they are designating these things].

"fread" has nothing to do with STREAMS (although, if you have a standard I/O
"stream" that refers to a STREAMS device, you can do an "fread" on a STREAMS
"stream"), and it is not a "system-call-primitive".  STREAMS "streams" are
referred to by file descriptors of the same sort as the file descriptors that
refer to regular files, and you can use the same "read" and "write" system
calls on file descriptors referring to STREAMS "streams" as you can on file
descriptors referring to plain files.  As such, "fread" will not "soon be the
new standard", and certainly won't replace "read".
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com

msf@amelia (Michael S. Fischbein) (10/16/87)

In article <31054@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes
(Quoting an earlier article):
>> > Why does the SVID stick read() and fread() in the same place?
>> 
>  I have no idea why they were stuck in the
>same place; it certainly doesn't reflect the way this stuff is actually
>packaged.  If there is some notion that the stuff in BA_OS should represent
>"system calls" (whatever that means - on *some* systems it means "routines
>consisting of a tiny wrapper around a trap", but not on others), "fread" - and
>"fopen", which is also in BA_OS - certainly doesn't belong there;

To quote from SVID, v1, section 3.1, which lists BA_OS routines:
  "Table 3-1 lists the Operating System Service Routines whose run-time
   behaviour must be supported by any implementation of the Base System"

Both read(2) and fread(3) are in the list [1].  Note the SVID does not mention
any distinction between the UNIX manual chapter 2 and chapter 3 routines;
which is where is implementation dependent;  what is required is that the
semantics of the call are supported.  The programmer does not need to be
concerned with chapter 2 / chapter 3 dichotomies unless efficiency is a
paramount concern; and then portability would be ignored anyway.

Note also that FREAD(BA_OS) is in the first set of routines on the list,
which "... should fulfill the needs of most application-programs," and
READ(BA_OS) is in the second set, which "should be used by application-
programs only when some special need requires it."


I don't read the SVID as requiring any routine to be a "trap" vs a
"system call."  In fact, there could conceivably be implementations
fully SVID conformant with NO traps, just real live subroutine calls
with the traps buried fairly deeply.  Think about hosted systems,
for example.

[1] More properly and pedantically, routines with calling semantics
identical to read in chapter 2 of the UNIX Programmer's Manual and
fread of chapter 3.  

		mike

Michael Fischbein                 msf@prandtl.nas.nasa.gov
                                  ...!seismo!decuac!csmunix!icase!msf
These are my opinions and not necessarily official views of any
organization.

rwhite@nusdhub.UUCP (Robert C. White Jr.) (10/16/87)

In article <31054@sun.uucp>, guy%gorodish@Sun.COM (Guy Harris) writes:
> "fread" has nothing to do with STREAMS (although, if you have a standard I/O
> "stream" that refers to a STREAMS device, you can do an "fread" on a STREAMS
> "stream"),

Apparently I needed to use upper case.  On my system "STREAMS" are not
defined when compared with read() in many cases [most spesifically
network "STREAMS" module(s)] The fact that you "can do fread on a
"STREAMS" stream" was quite my point.

> and it is not a "system-call-primitive".

Also, quite my point.  It is not NOW a system call primitive, it
is a library routine, thats why I SAID FREAD(3S)!.

> STREAMS "streams" are
> referred to by file descriptors of the same sort as the file descriptors that
> refer to regular files,

It is therefore strange that my programmers refrence refers to a
function:

int fileno(stream)
FILE *stream;

under FERROR(3S) which: "returns the interger file descriptor associated
with the named _stream_<italics<; see _open(2)_<italics<.
 NOTE: Only GOD knows why they put it under FERROR(3S) but _they_
obviously wanted to make the distinction.

> and you can use the same "read" and "write" system
> calls on file descriptors referring to STREAMS "streams" as you can on file
> descriptors referring to plain files.

I have been given to beleive that this is not the case.  The C
use of read() on "STREAMS" such as standard input _BYPASSES_ the
STREAMS module and drivers and gets the file handle from the
lib, and uses it on the file directly.  The same holds true
for "normal" files.  If you use this on a STREAMS-only device
the bypassing of the stream device lets you read the transport
provider [in the case of networks] directly, dropping you two
or more layers in the 7-layer model.  if you want to read() the
data you need to tpush() the approprate emulator on the
STREAMS-head.  If you don't, you get trash, and if you do, you
are locked out of most of the STREAMS functions until you tpop()
the module off.  [For more information, get a book on using
the Transport Level Interface]
NOTE: when you use a _multiplexing_ stream head to deal with
iregular input from multiple sources as if it were a single
source, I havn't got the foggiest what read() does.

> As such, "fread" will not "soon be the
> new standard", and certainly won't replace "read".

FORTUNATELY <sp?> THIS IS _NOT_ WHAT I SAID.... WHERE DID YOU
GET _"replace"_ ??????????!

I SAID: <paraphrased> that finding read(2) AND fread(2)
may soon be the new standard.

YOU WILL PLEASE NOTE THE _AND_, "2"s, AND THE LACK OF A PERIOD, OR OTHER
DISTURBING PUNCTUATION IN THAT SENTENCE.  YOUR "ORIGINAL" RESTATED
QUESTION WAS "why are read() and fread() in the same place?" (in
SVID)  THIS IS THE QUESTION I ANSWERED HERE, AS SUPPOSITION, NO LESS.
If you are using vnews, I seguest you use "p" once or twice and read
the paragraph again.

IN THE FUTURE I WOULD APPRICIATE IT IF YOU WOULD DO THE FOLLOWING:
	1) ONLY QUOTE ME IN CONTEXT.
	2) READ BEFORE YOU FLAME.
	3) CHECK YOU MANUAL FOR _REFRENCES_ BEFORE YOU FLAME
	4) STOP TAKING EVERYTHING SO PERSONAL.

Rob.

p.s.  To anybody my previous posting confused, aparently I SHOULD
have used the uppercase when writing "streams".  If it's that
important, just read every occurance of "streams" as "STREAMS"

guy%gorodish@Sun.COM (Guy Harris) (10/16/87)

> I don't read the SVID as requiring any routine to be a "trap" vs a
> "system call."

Neither do I, which is why I merely said that BA_OS routines would be wrappers
around traps only on some systems.
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com

guy%gorodish@Sun.COM (Guy Harris) (10/17/87)

> Apparently I needed to use upper case.  On my system "STREAMS" are not
> defined when compared with read() in many cases [most spesifically
> network "STREAMS" module(s)] The fact that you "can do fread on a
> "STREAMS" stream" was quite my point.
> 
> > and it is not a "system-call-primitive".
> 
> Also, quite my point.  It is not NOW a system call primitive, it
> is a library routine, thats why I SAID FREAD(3S)!.

No, what you said was:

> On the other hand, an "fread" type of system-call-primitive is NECESSARY
> to interact with the streams modules in the kernel.

which is complete rubbish.  Prior to that, you said:

> The difference is that read() and its brethren use file
> to do all there opperations while fread() and it's brethren use
> streams.

> Apearently every stream has at least one file handle assoicated with it
> but the level and method that streams interact with the kernel
> are quite different than simple files.  That is "any Transport
> Level Interface" [network, etc.] MUST be a stream when you open
> it.  If you want to then use read() against it you must manually
> push a streams-module that will properly react to the read()
> calls.

from which it is extremely clear that when you said "streams" you meant
"streams" as supported by the STREAMS mechanism.  However, you do not need to
use this non-existent "fread" "system-call-primitive" to read from a "stream"
as supported by the STREAMS mechanism; "read" will do quite well.

> It is therefore strange that my programmers refrence refers to a
> function:
> 
> int fileno(stream)
> FILE *stream;
> 
> under FERROR(3S) which: "returns the interger file descriptor associated
> with the named _stream_<italics<; see _open(2)_<italics<.

Yes, but that refers to a standard I/O stream, not a STREAMS stream.  The two
*are* different.

> > and you can use the same "read" and "write" system
> > calls on file descriptors referring to STREAMS "streams" as you can on file
> > descriptors referring to plain files.
> 
> I have been given to beleive that this is not the case.  The C
> use of read() on "STREAMS" such as standard input _BYPASSES_ the
> STREAMS module and drivers and gets the file handle from the
> lib, and uses it on the file directly.  The same holds true
> for "normal" files.

What?  This is complete rubbish.  I don't know who got you to believe that, but
if that's what they really said I'd suggest you not believe them in the future.
If they *didn't* really say that, I suggest you learn enough about UNIX and the
STREAMS mechanism to be able to understand what they say in the future.

You CAN NOT "bypass the STREAMS module and driver" by using "read".  "read"
bypasses any *standard I/O buffering* that would be done by e.g. "fread";
however, this has nothing whatsoever to do with STREAMS modules or drivers.

> If you use this on a STREAMS-only device the bypassing of the stream device
> lets you read the transport provider [in the case of networks] directly,
> dropping you two or more layers in the 7-layer model.

What?  STREAMS modules tend to go up to the transport layer (or maybe the
session layer); other layers are generally implemented in user mode.

> if you want to read() the data you need to tpush() the approprate emulator
> on the STREAMS-head.

This is ONLY true if you're using the TLI interface.  STREAMS is a *general*
mechanism that can be used for things having nothing to do with networking; you
could, for example, have a STREAMS-based tty driver, in which case you'd damn
well better be able to do regular "read"s and "write"s!

> NOTE: when you use a _multiplexing_ stream head to deal with
> iregular input from multiple sources as if it were a single
> source, I havn't got the foggiest what read() does.

It reads whatever data is at the stream had for the stream that refers to the
multiplexor (there is no such thing as a "multiplexing stream head";
multiplexors are drivers at the bottom of the stream).  What did you *think* it
did?

> YOUR "ORIGINAL" RESTATED QUESTION WAS "why are read() and fread() in the
> same place?" (in SVID)  THIS IS THE QUESTION I ANSWERED HERE, AS
> SUPPOSITION, NO LESS.  If you are using vnews, I seguest you use "p" once
> or twice and read the paragraph again.

That wasn't *my* question.  That was somebody else's question.  If *you* are
using "vnews", I suggest you use "p" once or twice and read the articles again.

> p.s.  To anybody my previous posting confused, aparently I SHOULD
> have used the uppercase when writing "streams".  If it's that
> important, just read every occurance of "streams" as "STREAMS"

After performing this transformation, one gets:

> It is therefore strange that my programmers refrence refers to a
> function:

> int fileno(stream)
> FILE *stream;

> under FERROR(3S) which: "returns the interger file descriptor associated
> with the named STREAM<italics<...

which would imply that "fileno" is here dealing with STREAMS.  It is not; this
is complete rubbish.

It appears that the problem here is that you *still* haven't figured out is
that when discusing standard I/O, and when discussing STREAMS, the term
"stream" is used; however, they do not mean the same thing.
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com

rwhite@nusdhub.UUCP (Robert C. White Jr.) (10/18/87)

I will for the most par assume that everything you have told me is correct,
but as far as this:

In article <31154@sun.uucp>, guy%gorodish@Sun.COM (Guy Harris) writes:
> It reads whatever data is at the stream had for the stream that refers to the
> multiplexor (there is no such thing as a "multiplexing stream head";
> multiplexors are drivers at the bottom of the stream).  What did you *think* it
> did?

BULL $#!+

And I quote: [UNIX System V Streams Primer pp 6-7]

	STREAMS multiplexing supports teh development of internetworking
protocols such as IP and ISO CLNS, and the processing of interleaved data
streams such as in SNA, X.25, and Terminal window facilities.

	STREAMS multiplexors (also called psudo-device drivers) are created
in the kernel by interconnecting multiple Streams.  Conceptually, there are
two kinds of multiplexors that developers can build with STREAMS: upper
and lower multiplexors.  Lower multiplexors have multiple lower Streams
between device drivers and the multiplexor, and upper multiplexors have
upper Streams between user processes the multiplexor.

[BAD GRAMMER IN THE LAST SENTENCE IS A DIRECT QUOTE]

This is then followed by a diagram which has the basic form:

[user process]
	|
[Multiplexor Driver]
          |   |   |
module:   A   B & C

etc. ad nasuim.

It goes on to talk about using a single multiplexing stream head to
control different modules with ioctl() and the like, followed by
the quote:

"The Facility allows users to set up the inter-module/driver plumbing to
create multiplexor configurations of generally unlimited interconnection."

Perhaps multiplexing is why ther is a poll() system call.
If the multiplexing were only at the bottom, what would this be for?

In the other issues I must say you get better marks than I.  I found
the miss refrenced passage about read and write.

[pp 7-1]

DRIVERS:

	At the interface to hardware devices, character I/O drivers have
interrupt entry points; at the system interface, those same drivers generally
have direct entry points (routines) to process open, close, read, write and
ioctl system calls.

	STREAMS device drivers have similar interrupt entry points at the
hardware device interface and have direct entry points only for open and
close system calls.  These entry points are accessed vi STREAMS, and the 
call formats differ from character device drivers.  The put procedure is a
drivers third entry point, but it is a message (not system) interface.  The
Stream head translates write and ioctl calls into messages and sends them
downstream to be processed by the driver's write QUEUE put procedure.
read is seen directly only by the Stream head, which contains functions
required to process system calls. [etc.]

- - - - - - - 

What this means is that my read and fread coments were someware in the
neighbor hood of "COMPLEETLY WRONG".  I had thought that when you
pushed the module on the stream, it became the new "head"  This
snoballed into a total mis-understanding on my part, and hence the
previousley posted bullshit.

SO how about this: I'm partly right, your mostly right, and neither of
	us will take it personally.

Rob.

guy%gorodish@Sun.COM (Guy Harris) (10/18/87)

> > It reads whatever data is at the stream had for the stream that refers to
> > the multiplexor (there is no such thing as a "multiplexing stream head";
> > multiplexors are drivers at the bottom of the stream).  What did you
> > *think* it did?

> [user process]
> 	|
> [Multiplexor Driver]
>           |   |   |
> module:   A   B & C
> 
> etc. ad nasuim.

For some reason, probably to simplify the diagram, they omitted the stream head
from this diagram.  It's still there; it's *always* there in *any* stream.

> Perhaps multiplexing is why ther is a poll() system call.
> If the multiplexing were only at the bottom, what would this be for?

Nope.  "poll" is just 4.2BSD's "select" with a propellor beanie.  It has
nothing to do with STREAMS multiplexor drivers; it is used for "multiplexing",
in a sense.  It is used if a program wants to manage several streams,
"multiplexing", if you will, its time between servicing those streams.

"poll" is given a set of cookies, each one of which expresses interest in the
state of various file descriptors that refer to streams.  The caller of "poll"
can ask whether a "read" or "getmsg" can be done on the stream without blocking
(i.e., data is present at the stream head); whether a "write" or "putmsg" can
be done on the stream without blocking (i.e., there is not so much data queued
somewhere that flow control would cause a "write" or "putmsg" to block); or
whether a high-priority message is present at the stream head.  (These provide
basically the same functionality as the "read", "write", and "exceptional
condition" bit masks for the "select" system call.)

It blocks until at least one of the streams referred to is in the state or
states for which interest has been expressed for that stream.  It will also
return if one of the streams gets an error or hangup message.

Programs that use "poll" (or "select") are often written as a big loop with a
"poll" at the top.  If the "poll" returns, it means that some amount of I/O can
be done on some subset of the streams in question without blocking.  It does
whatever I/O it can, and returns to the top of the loop.  The program will
typically put descriptors on which "write"s or "putmsg"s are to be done in
non-blocking mode, so that you can attempt to write as much data as possible,
and the system will only write as much data as can be written without blocking
and tell you how much that was.  This is often a good idea for streams on which
"read"s or "getmsg"s are to be done, as well, since "poll" (or "select") can
return because there is data to be read, but the data could be flushed (due
e.g. to an M_FLUSH message going upstream) before the "read" is actually done.
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com

rwhite@nusdhub.UUCP (Robert C. White Jr.) (10/20/87)

In article <31166@sun.uucp>, guy%gorodish@Sun.COM (Guy Harris) writes:
> > [user process]
> > 	|
> > [Multiplexor Driver]
> >           |   |   |
> > module:   A   B & C
> > 
> > etc. ad nasuim.
> 
> For some reason, probably to simplify the diagram, they omitted the stream head
> from this diagram.  It's still there; it's *always* there in *any* stream.


The impression the entire text [Deleted for brevity :-)] gave was that the
"multiplexor driver" was the head of a stream [perhaps "special" in
some way] into which connections to the heads of other STREAMS could be
pushed [or ioctl(ed) in some way. i.e.:

"Upper multiplexors are a spesific application of standard STREAMS
facilities that support multiple minor devices in a device driver."

Im begining to get the feeling that this STREAMS primer should be used
for "Priming" bonfires.  This thing is full of mixed messages.

Would it therefore be more correct to have something like:

Process       A           B           C          D
              |           |           |          |
Head	     (a)	 (b)	     (c)	(d)
              |           |           |          |
	[		Upper Multiplexor		]
				|
				|
	[		Lower Multiplexor		]
		|		|		|	]
Device		1		2		3


Or is the entire thing even more convoluted???

Rob.