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