views:

3871

answers:

1

If I have a program which creates and attempts to open a named pipe using mkfifo, how can I open a pipe for reading or writing without blocking?

Specifically, I'm writing a C program which can be run with or without a gui (written in Java).

In the C program, I successfully create the named pipes using mkfifo, however when I do

FILE* in = fopen(PIPE_IN, "r"); /* Where PIPE_IN is the filename*/

fopen doesn't return until the GUI opens that pipe for writing. What I wish to do is have that pipe ready to be read once (if) the GUI decides to write to it - I'll be putting the file descriptor in a select() call. It's reasonable to expect that the java GUI may never actually be started, so I cannot rely on it to open the other end of the pipe at any specific point or even at all.

I will also have a second pipe open for writing, and I assume I will have the same problem. Further, I can't set O_NONBLOCK on an output pipe that has no reader.

Any suggestions?

(This is running on a linux system)

+2  A: 

You could open() your pipe O_RDONLY | O_NONBLOCK, and if you want the C stream, you can get it with fdopen(). However, there might be a problem with the select() - AFAIK, a pipe fd open for reading that has no writer is always prepared for reading, and read() returns 0, so the select() would fire indefinitely.

A kludgy way of overcoming this would be to open the pipe O_RDWR; that is, have at least one writer (your C++ program). Which would solve your problem anyway.

jpalecek
I'll give that a shot for the reader - but I can't set O_NONBLOCK on an output pipe...
Zxaos
The POSIX standard says (of select()): "A descriptor shall be considered ready for reading when a call to an input function with O_NONBLOCK clear would not block, whether or not the function would transfer data successfully." (POSIX.1:2008).
Jonathan Leffler
Opening the pipe O_RDWR would lead to deadlock when the program reads (or writes) - unless there is actually another process also with the pipe open.
Jonathan Leffler
@Jonathan Leffler - But could I open it RDWR and just poll it to see when another process actually has written to it? That shouldn't cause deadlocks, right?
Zxaos
Yes, and this should block in select(). No such solutions for the writing end of a pipe, probably the best thing you could do is open the writing end after you've received some prompt from the Java program
jpalecek
@jpalecek Yeah, I realized that's what I had to do last night after thinking about why tinkertim asked about the order in the comment to the original question.
Zxaos