But I don't wanna do non-blocking I/O...

John Chambers jc at minya.UUCP
Fri Jun 15 11:37:50 AEST 1990


In article <407 at minya.UUCP>, jc at minya.UUCP (John Chambers) writes:

[Well, here I go doing a followup to my own article... ;-]

> > You should RTFM (specifically the read(2) man page). Therein you should
> > find a paragraph similar to the following:
> > 	When attempting to read a file associated with a tty that has no data
> > 	currently available:
> > 		If O_NDELAY is set, the read will return 0.
> > 		If O_NDELAY is clear, the read will block until data becomes
> > 		available.
> 
> Hey, whadday you know, I actually found it in one copy of TFM.  I first
> looked it up in various other Unix manuals I happen to have lying about
> (souvenirs, you know), and didn't find it in them, but I just got a copy
> of the System V/386 Release 32 (really!) Programmer's Reverence Manual
> (that was a typo, too, honest it was, but it's too good to correct ;-), 
> and there is is in black and white....  In the morning, I'll check with 
> the Ultrix manuals at work and see what they say.  If they're true to
> form, they won't mention the subject; anyway, the code works find on
> Ultrix, since I figured out that PMAX/Ultrix doesn't do non-blocking I/O.

Well, I looked it up in the Ultrix manuals, and what they have to say is
even more fun than the Sys/V manuals.  The read(2) page doesn't make any
mention of the topic.  The open(2) page says that O_NDELAY and O_NONBLOCK
are the same, and both cause the open to return immediately (which is a
bald-faced lie on the PMAX, but that's a different problem).  There's no
hint as to the behavior of later calls of read().  You are referred to
the fcntl(2) page, which lists F_GETFL and F_SETFL for arg 2, and FNDELAY
as one of the flags for arg 3.  A simple experiment shows that a read()
after an open(...,O_NDELAY|...) does indeed block, but I can't find this
documented anywhere, so perhaps it's best not to rely on it.

The real fun starts when you do a test that seems to verify that a call
of fcntl(f,F_SETFL,FNDELAY) does indeed cause non-blocking I/O, at least
on VAX/Ultrix.  But it turns out that this call is incorrect.  Why?  The
hint is that, while there is are codes for getting and setting the status
flags, there is no code for clearing a flag.  After the further hint that
the correct way to turn a status flag on or off always requires two system
calls, I'll let the reader puzzle the rest out.  Of course, the manual
pages don't contain any actual examples.  (And I could still misunderstand
what they say; it's happened before.)

I've been trying, in essence, to write a function:
	nbio(fd,flag)
which turns nonblocking I/O on or off depending on whether flag is true
or false.  It appears that this function must have lots of #ifdefs to 
work right.  It also appears that some manuals don't commit themselves
as to whether O_NDELAY (or O_NONBLOCK) leaves the file in a blocking or
a nonblocking state, so if you use O_NDELAY in open(), it is probably
a good idea to *always* call a function like nbio() to ensure the desired
behavior.

It might be interesting to collect together the code that does this 
job on various releases of Unix.   It should be maybe 3-6 lines of 
code on most systems.  If a few folks out there would try their hand 
at writing nbio(), testing it (;-), and sending the results to me, 
I'd be happy to post the results.  Note that this function should 
work correctly regardless of the current blocking state of the file, 
which isn't known if you've called *any* routine that you didn't write 
(or you are running on Ultrix ;-).  Any hackers out there find this 
interesting?

I wonder what the latest POSIX standard says on the topic?

-- 
Uucp: ...!{harvard.edu,ima.com,eddie.mit.edu}!minya!jc (John Chambers)
Home: 1-617-484-6393
Work: 1-508-952-3274
Cute-Saying: [I've gotta get a new one of these some day.]



More information about the Comp.unix.wizards mailing list