I have gone through a variaty of different linux named pipe client/server implementations but most of them use the blocking defaults on reads/writes.
As I am already
According to open(2) man page, you can pass O_RDONLY|O_NONBLOCK
or O_WRONLY|O_NONBLOCK
to avoid the open
syscall to be blocked (you'll get errno == ENXIO
in that case)
As I commented read also the fifo(7) and mkfifo(3) man pages.
First, some preliminaries:
Using O_NONBLOCK
and poll()
is common practice -- not the other way around. To work successfully, you need to be sure to handle all poll()
and read()
return states correctly:
read()
return value of 0
means EOF -- the other side has closed its connection. This corresponds (usually, but not on all OSes) to poll()
returning a POLLHUP
revent. You may want to check for POLLHUP
before attempting read()
, but it is not absolutely necessary since read()
is guaranteed to return 0
after the writing side has closed. read()
before a writer has connected, and you have O_RDONLY | O_NONBLOCK
, you will get EOF (read()
returning 0
) repeatedly, as you've noticed. However, if you use poll()
to wait for a POLLIN
event before calling read()
, it will wait for the writer to connect, and not produce the EOFs. read()
return value -1
usually means error. However, if errno == EAGAIN
, this simply means there is no more data available right now and you're not blocking, so you can go back to poll()
in case other devices need handling. If errno == EINTR
, then read()
was interrupted before reading any data, and you can either go back to poll()
or simply call read()
again immediately.Now, for Linux:
O_RDONLY
, then:
open()
will block until there is a corresponding writer open.poll()
will give a POLLIN
revent when data is ready to be read, or EOF occurs.read()
will block until either the requested number of bytes is read, the connection is closed (returns 0), it is interrupted by a signal, or some fatal IO error occurs. This blocking sort of defeats the purpose of using poll()
, which is why poll()
almost always is used with O_NONBLOCK
. You could use an alarm()
to wake up out of read()
after a timeout, but that's overly complicated.poll()
POLLHUP
revent and read()
will return 0
indefinitely afterwards. At this point, the reader must close its filehandle and reopen it.
O_RDONLY | O_NONBLOCK
, then:
open()
will not block.poll()
will give a POLLIN
revent when data is ready to be read, or EOF occurs. poll()
will also block until a writer is available, if none is present.read()
will either return -1 and set errno == EAGAIN
if the connection is still open, or it will return 0
if the connection is closed (EOF) or not yet opened by a writer. When errno == EAGAIN
, this means it's time to return to poll()
, since the connection is open but there is no more data. When errno == EINTR
, read()
has read no bytes yet and was interrupted by a signal, so it can be restarted.poll()
POLLHUP
revent, and read()
will return 0
indefinitely afterwards. At this point the reader must close its filehandle and reopen it.
O_RDWR
, then:
open()
will not block.poll()
will give a POLLIN
revent when data is ready to be read. However, for named pipes, EOF will not cause POLLIN
or POLLHUP
revents.read()
will block until the requested number of bytes is read, it is interrupted by a signal, or some other fatal IO error occurs. For named pipes, it will not return errno == EAGAIN
, nor will it even return 0
on EOF. It will just sit there until the exact number of bytes requested is read, or until it receives a signal (in which case it will return the number of bytes read so far, or return -1 and set errno == EINTR
if no bytes were read so far).O_RDWR | O_NONBLOCK
, then:
open()
will not block.poll()
will give a POLLIN
revent when data is ready to be read. However, EOF will not cause POLLIN
or POLLHUP
revents on named pipes.read()
will return -1
and set errno == EAGAIN
. This is the time to return to poll()
to wait for more data, possibly from other streams.As you are rightly concerned, using O_RDWR
with pipes is not standard, POSIX or elsewhere.
However, since this question seems to come up often, the best way on Linux to make "resilient named pipes" which stay alive even when one side closes, and which don't cause POLLHUP
revents or return 0
for read()
, is to use O_RDWR | O_NONBLOCK
.
I see three main ways of handling named pipes on Linux:
(Portable.) Without poll()
, and with a single pipe:
open(pipe, O_RDONLY);
read()
as much data as needed, possibly looping on read()
calls.
read() == -1
and errno == EINTR
, read()
all over again.read() == 0
, the connection is closed, and all data has been received. (Portable.) With poll()
, and with the expectation that pipes, even named ones, are only opened once, and that once they are closed, must be reopened by both reader and writer, setting up a new pipeline:
open(pipe, O_RDONLY | O_NONBLOCK);
poll()
for POLLIN
events, possibly on multiple pipes at once. (Note: This prevents read()
from getting multiple EOFs before a writer has connected.)read()
as much data as needed, possibly looping on read()
calls.
read() == -1
and errno == EAGAIN
, go back to poll()
step.read() == -1
and errno == EINTR
, read()
all over again.read() == 0
, the connection is closed, and you must terminate, or close and reopen the pipe.(Non-portable, Linux-specific.) With poll()
, and with the expectation that named pipes never terminate, and may be connected and disconnected multiple times:
open(pipe, O_RDWR | O_NONBLOCK);
poll()
for POLLIN
events, possibly on multiple pipes at once.read()
as much data as needed, possibly looping on read()
calls.
read() == -1
and errno == EAGAIN
, go back to poll()
step.read() == -1
and errno == EINTR
, read()
all over again.read() == 0
, something is wrong -- it shouldn't happen with O_RDWR
on named pipes, but only with O_RDONLY
or unnamed pipes; it indicates a closed pipe which must be closed and re-opened. If you mix named and unnamed pipes in the same poll()
event-handling loop, this case may still need to be handled.