A question about read() system call!!
Larry Martell
larry at st-andy.uucp
Sat May 25 01:28:02 AEST 1991
In article <azaC8VCoBMwpU at idunno.Princeton.EDU> subbarao at phoenix.Princeton.EDU (Kartik Subbarao) writes:
>In article <1361 at anprda.atson.asahi-np.co.jp> akira at anprda.atson.asahi-np.co.jp (Akira Takiguchi) writes:
>
>>>If the file is not open yet, you can specify the O_NDELAY option when you
>>>open the file.
>>
>> This has nothing to do with the problem. It makes open(2) non-blocking
>>but not read(2).
>
>Not on all types of machines. From our open(2v) man page: (SunOS 4.1.1)
>
> If the O_NDELAY or O_NONBLOCK flag is set on a call to
> open(), the corresponding flag is set for that file
> descriptor (see fcntl(2V)) and subsequent reads and writes
> to that descriptor will not block (see read(2V) and
> write(2V)).
I'm confused. I always thought that opening with O_NDELAY allowed non blocking
I/O. I fact I'm sure that in the past I wrote programs that assumed this to be
true, and they worked. With all this discussion going on I tried it out
(on a 4/490 running SunOS 4.1), and I was suprised to find that opening
with O_NDELAY ***did not*** allow non blocking reads. A call to fcntl, setting
O_NDELAY, was needed to allow non blocking I/O.
The excerpt from the open(2V) man page quoted above is under the section
entitled "SYSTEM V DESCRIPTION". From the intro(2) man page:
Compile programs for the System V environment using
/usr/5bin/cc. Compile programs for the default SunOS
environment using /usr/bin/cc.
Did Sun change this at some point? Has it always been like this.
I just tried a experiment and found that an open with O_NDELAY of a serial
port does not cause non blocking I/O. As I said above, a call to fcntl,
setting O_NDELAY, will allow non blocking I/O. After this a read of the
port returns -1 with errno set to EWOULDBLOCK. That's what I expected.
The same test on both a FIFO and a file, however, produced different results.
In these cases the open with O_NDELAY **did** allow non blocking I/O. No call
to fcntl was needed. However, the reads returned 0. Not what I expected.
>From the read(2V) man pages:
When attempting to read from a descriptor associated with an
empty pipe, socket, FIFO, or stream:
+ If the object the descriptor is associated with is marked
for 4.2BSD-style non-blocking I/O (with the FIONBIO
ioctl() request or a call to fcntl(2V) using the FNDELAY
flag from <sys/file.h> or the O_NDELAY flag from
<fcntl.h> in the 4.2BSD environment), the read will
return -1 and errno will be set to EWOULDBLOCK.
+ If the descriptor is marked for System V-style non-
blocking I/O (using fcntl() with the FNBIO flag from
<sys/file.h> or the O_NDELAY flag from <fcntl.h> in the
System V environment), and does not refer to a stream,
the read will return 0. Note: this is indistinguishable
from EOF.
I compiled my programs with the unbundled C compiler (/usr/lang/cc), not
/usr/5bin/cc or /usr/bin/cc. So I guess that complier gives me System V
behavior.
I have programs I wrote under 3.5 that open FIFO's with O_NDELAY, do not
set O_NDELAY with fcntl, and test for errno == EWOULDBLOCK when the read
returns -1. I'm sure that this is the behavior I got under that system. When
we got rid of our Sun 3's and got a 4/490, IPC's and SLC's, I just moved the
sources, compiled them, and they worked fine. Now I think that they are just
waiting to break. As I asked before, did the stuff change anywhere along the
line from 3.5 to 4.1? Can anyone shed some light on this situation?
--
Larry Martell "Opinions are like assholes; everybody has one,
212-668-9478 but nobody wants to look at the other guys"
uunet!st-andy!larry
More information about the Comp.unix.questions
mailing list