[comp.unix.questions] A question about read

ashraf@maccs.dcss.mcmaster.ca (Ashraf Mahmoud) (05/22/91)

Hello Every Body,

  I wonder if I can get help regarding the unix system call "read()".
When a program executes this system call to read from an empty pipeline,  
shouldn't it return zero ( nothing is read ) and passes control to the next 
statement? I think it remains stuck waiting for something to be put it the 
pipeline. How can I overcome this behaviour? That is making it pass control 
to next statement even if pipeline is empty. I would appreciate responses.

Ashraf   
McMaster U.
   

jik@athena.mit.edu (Jonathan I. Kamens) (05/22/91)

  The default behavior of read() is to wait until there is something to read
unless either (a) you have reached EOF, in which case it returns 0, or (b)
there has been some error, in which case it returns -1.

  The "Frequently Asked Questions about Unix" posting in this newsgroup
discusses, in question number 7 how to check if there are characters to read
without reading them, and how to read if there are characters to read but
return otherwise.

  If the FAQ posting has expired at your site, you can get a copy using the
instructions at the end of this message.  It is usually a good idea to read
the FAQ posting, or at least to scan it looking for material that might help
you, before posting a question in any of the comp.unix newsgroups.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710
-- 
        Subject: Frequently Asked Questions about Unix - with Answers [Monthly posting]
        Newsgroups: comp.unix.questions

        Available via anonymous ftp from pit-manager.mit.edu (18.72.1.58)
        in the file

        /pub/usenet/comp.unix.questions/Frequently_Asked_Questions_about_Unix_-_with_Answers_[Monthly_posting]

        Available from mail-server@pit-manager.mit.edu by sending a message
        containing

        send usenet/comp.unix.questions/Frequently_Asked_Questions_about_Unix_-_with_Answers_[Monthly_posting]

        Send a message containing "help" to get general information about the
        mail server.

dougy@hpsciz.sc.hp.com (Doug Yip) (05/23/91)

>  I wonder if I can get help regarding the unix system call "read()".
>When a program executes this system call to read from an empty pipeline,  
>shouldn't it return zero ( nothing is read ) and passes control to the next 
>statement? I think it remains stuck waiting for something to be put it the 
>pipeline. How can I overcome this behaviour? That is making it pass control 
>to next statement even if pipeline is empty. I would appreciate responses.

   
There are two options to solve this problem:

If the file is already open, you can do a fcntl(fd,F_SETFL,O_NDELAY).

If the file is not open yet, you can specify the O_NDELAY option when you
open the file.

You need to include the following files for the options to work according
to my manual:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

les@chinet.chi.il.us (Leslie Mikesell) (05/23/91)

In article <28398698.26968@maccs.dcss.mcmaster.ca> ashraf@maccs.dcss.mcmaster.ca (Ashraf Mahmoud) writes:

>  I wonder if I can get help regarding the unix system call "read()".
>When a program executes this system call to read from an empty pipeline,  
>shouldn't it return zero ( nothing is read ) and passes control to the next 
>statement? I think it remains stuck waiting for something to be put it the 
>pipeline. How can I overcome this behaviour? 

If you really want to do it that way you can use fcntl() to set the
O_NDELAY flag.  However, unless you are very careful to limit the
speed at which you loop through the read() requests you are likely
to swamp the machine with hundreds of system calls per second.  Sometimes
there are better ways to design a program - sometimes a 1 second
sleep in the loop will keep everybody happy.

Les Mikesell
  les@chinet.chi.il.us

toma@swsrv1.cirr.com (Tom Armistead) (05/23/91)

In article <28398698.26968@maccs.dcss.mcmaster.ca> ashraf@maccs.dcss.mcmaster.ca (Ashraf Mahmoud) writes:
>
>Hello Every Body,
>
>  I wonder if I can get help regarding the unix system call "read()".
>When a program executes this system call to read from an empty pipeline,  
>shouldn't it return zero ( nothing is read ) and passes control to the next 
>statement? I think it remains stuck waiting for something to be put it the 
>pipeline. How can I overcome this behaviour? That is making it pass control 
>to next statement even if pipeline is empty. I would appreciate responses.
>
>Ashraf   
>McMaster U.
>   

You need to use the O_NDELAY flags for open, e.g.

	open( "FILE", O_RDONLY|O_NDELAY )

This the 'non-blocking' I/O flag.  When you open a pipe in normal mode for
read and no other process has it opened for write, the open() will hang
(or if you try to open it for write and no one has it open for read).

With the O_NDELAY set, the open will fail (with -1) and errno will be set to
?(I think)? ENXIO.

Tom
-- 
Tom Armistead - Software Services - 2918 Dukeswood Dr. - Garland, Tx  75040
===========================================================================
toma@swsrv1.cirr.com                {egsner,letni,ozdaltx,void}!swsrv1!toma

akira@atson.asahi-np.co.jp (Akira Takiguchi) (05/23/91)

In article <690002@hpsciz.sc.hp.com> dougy@hpsciz.sc.hp.com (Doug Yip) writes:
[noblocking read(2)]
>If the file is already open, you can do a fcntl(fd,F_SETFL,O_NDELAY).

     ok.

>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).
-- 
       |    Akira Takiguchi  at ATSON, Inc. (a subsidiary of the Asahi Shimbun)
       |                WAKO GINZA bldg.  8-10-4 Ginza Chuo-ku Tokyo 104  Japan
       | Phone +81 3 3289 7051  Fax +81 3 3289 7066  SORRY, EMAIL NOT AVAILABLE

subbarao@phoenix.Princeton.EDU (Kartik Subbarao) (05/23/91)

In article <1361@anprda.atson.asahi-np.co.jp> akira@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)).


		-Kartik


--
internet% ypwhich

subbarao@phoenix.Princeton.EDU -| Internet
kartik@silvertone.Princeton.EDU (NeXT mail)  
SUBBARAO@PUCC.BITNET			          - Bitnet

rearl@watnxt3.ucr.edu (Robert Earl) (05/23/91)

In article <1991May23.031442.25522@swsrv1.cirr.com> toma@swsrv1.cirr.com (Tom Armistead) writes:

|   You need to use the O_NDELAY flags for open, e.g.
|
|	   open( "FILE", O_RDONLY|O_NDELAY )

Remember that some versions of open(2) take three arguments, path,
flags, and mode.

|   With the O_NDELAY set, the open will fail (with -1) and errno will be set to
|   ?(I think)? ENXIO.

The manpage says that all O_NDELAY does is causes open() to return
immediately with a file descriptor if the operation would block
otherwise.  The first read() on the descriptor will return EWOULDBLOCK
(on the systems I checked.)  ENXIO is "No such device or address".
So, you must use the FNDELAY (aka O_NDELAY) fcntl once the descriptor
is open.


--
______________________________________________________________________
			\					
 robert earl		/	"Love is a many splintered thing"
 rearl@watnxt3.ucr.edu	\		--Sisters of Mercy
 rearl@gnu.ai.mit.edu	/

mouse@thunder.mcrcim.mcgill.edu (der Mouse) (05/24/91)

In article <28398698.26968@maccs.dcss.mcmaster.ca>, ashraf@maccs.dcss.mcmaster.ca (Ashraf Mahmoud) writes:

> When a program executes this system call [read()] to read from an
> empty pipeline, shouldn't it return zero ( nothing is read ) and
> passes control to the next statement?  I think it remains stuck
> waiting for something to be put it the pipeline.

You are correct; this is how it's supposed to work.  read() is supposed
to return immediately when there's nothing to read only when the pipe
has only one end (ie, the write end of the pipe has been closed down)
or if the file descriptor has been marked non-blocking, on systems that
support this.

If by "empty" you mean that the program writing to the pipe has closed
the pipe (for example, if it's died), then yes, something is wrong.
Most likely another process has the write end still open.

> How can I overcome this behaviour?  That is making it pass control to
> next statement even if pipeline is empty.

If your operating system supports it, set non-blocking mode on the
pipe.  Look at the fcntl() call for the F_SETFL request, or
I'm-not-sure-where for the FIONBIO ioctl.

If not, you're pretty much out of luck.  You may be able to get by by
setting a timeout to break out of the read.

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

larry@st-andy.uucp (Larry Martell) (05/24/91)

In article <azaC8VCoBMwpU@idunno.Princeton.EDU> subbarao@phoenix.Princeton.EDU (Kartik Subbarao) writes:
>In article <1361@anprda.atson.asahi-np.co.jp> akira@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

shane@inferno.peri.com (Shane Bouslough) (05/30/91)

From article <1361@anprda.atson.asahi-np.co.jp>
	akira@atson.asahi-np.co.jp (Akira Takiguchi) speaks too soon:
> 
>>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).

BZZZZZZZZZZZ! <- game show buzzer

And the Manual looketh upon O_NDELAY and spake:

OPEN(2)
	O_NDELAY This flag may affect subsequent reads and writes. See
	read(2) and write(2).

READ(2)
	When attempting to read from an empty pipe (or FIFO):
		If O_NDELAY is set, the read will return a 0.
		If O_NDELAY is clear, the read will block until data
		is written to the file or the file is no longer
		open for writing.

And the Manual saw that O_NDELAY was good.

> -- 
>        |    Akira Takiguchi  at ATSON, Inc. (a subsidiary of the Asahi Shimbun)
>        |                WAKO GINZA bldg.  8-10-4 Ginza Chuo-ku Tokyo 104  Japan
>        | Phone +81 3 3289 7051  Fax +81 3 3289 7066  SORRY, EMAIL NOT AVAILABLE


-- 
Shane Bouslough    |  ...!rutgers!mcdhup!inferno!shane           516-467-0500
Periphonics Corp.  |                                             Ride Bike!
4000 Veterans Hwy. |  "We're talking Mega-Ecstasy-Bliss!!!"
Bohemia, NY 11716  |                              -David Lister, Red Dwarf

akira@atson.asahi-np.co.jp (Akira Takiguchi) (05/30/91)

In article <1991May29.180840.6512@inferno.peri.com> shane@inferno.peri.com (Shane Bouslough) writes:
[I pointed out that open(,O_NDELAY,) doesn't make read() non-blocking.
>BZZZZZZZZZZZ! <- game show buzzer
>
>And the Manual looketh upon O_NDELAY and spake:
[deleted]

     I was half wrong, since there are systems (SysV, posix) that makes read
non-blocking if the descriptor is opened with O_NDELAY (or O_NONBLOCK) set.
But there ARE systems (BSD) that behaves differently so it is safer to
recommend fcntl(O_NDELAY) especially when the original poster didn't mention
about his OS.
-- 
       |    Akira Takiguchi  at ATSON, Inc. (a subsidiary of the Asahi Shimbun)
       |                WAKO GINZA bldg.  8-10-4 Ginza Chuo-ku Tokyo 104  Japan
       | Phone +81 3 3289 7051  Fax +81 3 3289 7066  SORRY, EMAIL NOT AVAILABLE