From: Nat Pryce Date: 2002-01-27T22:15:30+09:00 Subject: Re: listening on a fifo > I'm using the following to have a program listen on a fifo and take > action whenever input becomes available. The fifo should be used like > a device under /dev, like: > > $ echo 'hello world' >fifo > > Is there any better/nicer way? > > > fifo = 'foo' > `mkfifo #{fifo}` if not File.exists?(fifo) This line has a race condition if two processes are trying to create the fifo. It is possible for one process to determine that the fifo doesn't exist and then lose the CPU before creating the fifo. The second process could then create the fifo. The execution of mkfifo by the first process would then fail when it tried to create the fifo. I prefer to create the fifo by hand, as part of the installation and configuration of the system, and then pass the name of the fifo to the processes that communicate through it as a command-line argument, for example. So, if the fifo doesn't exist, it's a problem for the administrator to sort out. If you want your process to create the fifo if it doesn't exist, wrap the line that calls mkfifo in an exception handler. > loop do > f = File.open(fifo, File::RDONLY | File::NONBLOCK) > select [f] > p f.read > end Be careful reading from a fifo in non-blocking mode. A call to f.read might not return the entire message sent by the writer, if the message is larger then the size of the fifo's buffers in the operating system. Since a fifo is an undelimted stream of bytes you'll have to define a protocol by which the reader and writer delimit messages. E.g. write the size at the start of each message or delimit messages by newline characters. Furthermore, although Linux defines the semantics of opening a fifo in non-blocking mode, POSIX does not, so that code might not be portable across all POSIX implementations. Finally, opening a fifo for non-blocking *writes* will result in SIGPIPE signals being sent to your process if the fifo has not already been opened for reading. You'll have to set up signal handers in the writer (if it's using non-blocking IO), or the SIGPIPE signal will terminate the process. Cheers, Nat.