[comp.os.minix] read/writes to pipes with O_NDELAY set

leo@marco.UUCP (Matthias Pfaller) (09/14/90)

according to the manuals of our Unix-box reads and writes to a pipe
with O_NDELAY set should behave as follows:
>
>          If the file being written is a pipe (or FIFO) and the
>          O_NDELAY flag of the file flag word is set, then write to a
>          full pipe (or FIFO) will return a count of 0.  Otherwise
>          (O_NDELAY clear), writes to a full pipe (or FIFO) will block
>          until space becomes available.
>
>
>          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.
>
Minix returns EAGAIN; what is correct, what says Posix?
	Matthias Pfaller

dpi@loft386.uucp (Doug Ingraham) (09/15/90)

In article <478@alice.marco.UUCP>, leo@marco.UUCP (Matthias Pfaller) writes:
> according to the manuals of our Unix-box reads and writes to a pipe
> with O_NDELAY set should behave as follows:
> >
> >          If the file being written is a pipe (or FIFO) and the
> >          O_NDELAY flag of the file flag word is set, then write to a
> >          full pipe (or FIFO) will return a count of 0.  Otherwise
> >          (O_NDELAY clear), writes to a full pipe (or FIFO) will block
> >          until space becomes available.
> >
> >
> >          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.
> >
> Minix returns EAGAIN; what is correct, what says Posix?
> 	Matthias Pfaller

POSIX changed O_NDELAY to O_NONBLOCK.  The reasoning is detailed in section
B.6 pp250-251.  They say that "Systems may choose to implement both O_NDELAY
and O_NONBLOCK, and there is no conflict as long as an application does not
turn both flags on at the same time."  I am slightly confused by this.  I
think that the use of O_NDELAY results in a non-standard conforming program.

On the matter of blocked reads there is line on page 255 that I think will
answer your question.

"Where the standard requires -1 returned and errno set to [EAGAIN], most
historical implementations return zero (with the O_NDELAY flag set: that
flag is the historical predecessor of O_NONBLOCK, but is not itself in the
standard).  The error indications in the standard were chosen so that an
application can distinguish these cases from end-of-file.  While write()
cannot receive an indication of end-of-file, read() can, and the Working
group chose to make the two functions have similar return values."

On page 112 are the rules that define what must happen:

When attempting to read from an empty pipe (or FIFO):

1) If no process has the pipe open for writing, read() shall return zero
   to indicate end-of-file.
2) If some process has the pipe open for writing and O_NONBLOCK is set,
   read() shall return -1 and set errno to [EAGAIN].
3) If some process has the pipe open for writing and O_NONBLOCK is clear,
   read() shall block until some data is written or the pipe is closed
   by all processes that had opened the pipe for writing.

When attempting to read a file (other than a pipe or FIFO) that supports
non-blocking reads and has no data currently available:
1) If O_NONBLOCK is set, read() shall return -1 and set errno to [EAGAIN].
2) If O_NONBLOCK is clear, read() shall block until some data becomes
   available.
3) The use of the O_NONBLOCK flag has no effect if there is some data
   available.

I think that MINIX is correct in returning EAGAIN as far as POSIX is
concerned.  I am not yet running 1.5 so I can't check to see if O_NONBLOCK
is also supported.

I think this answers your question.

-- 
Doug Ingraham (SysAdmin)
Lofty Pursuits (Public Access for Rapid City SD USA)
uunet!loft386!dpi