23

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)

Jive Dadson
  • 16,680
  • 9
  • 52
  • 65
Zxaos
  • 7,791
  • 12
  • 47
  • 61
  • Do you need to open the output pipe prior to select() firing on the input pipe? – Tim Post Feb 24 '09 at 03:47
  • @tinkertim - I suppose technically not - I had set them both up in a setup function, but I could just set up the output pipe first and then call select, why? – Zxaos Feb 24 '09 at 04:47

1 Answers1

22

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
jpalecek
  • 47,058
  • 7
  • 102
  • 144
  • 1
    I'll give that a shot for the reader - but I can't set O_NONBLOCK on an output pipe... – Zxaos Feb 24 '09 at 03:43
  • 1
    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 Feb 24 '09 at 04:13
  • 2
    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 Feb 24 '09 at 04:15
  • 1
    @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 Feb 24 '09 at 04:46
  • 1
    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 Feb 24 '09 at 09:41
  • @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 Feb 24 '09 at 16:38