On Wed, 25 Aug 2004, Scott Rubin wrote:

> Ok, this problem I'm having is a little bit strange. I have two seperate 
> processes running as part of this application. One process is written in C 
> and the other process is written in Ruby.  To communicate between the two 
> processes I have two fifos in the file system.  One fifo sends ASCII strings 
> in one direction, and the other fifo goes in the other direction.
>
> Now, the problem is that pipes need to be opened on the reading end first. So 
> I have it coded like this.
>
> # open the incoming fifo
> infifo = File.open( "infifo", IO::NONBLOCK | IO::RDONLY )
> 	# launch the C process
> pid = fork do exec( "cprocess" ) end
>
> # open the outfifo
> outfifo = File.open( "outfifo", "w" )
>
> There is an obvious problem here. The problem is that at some point the 
> cprocess opens the outfifo on the other end. And the ruby program cannot open 
> the outfifo for writing before the cprocess opens it for reading. I tried to 
> place the outfifo = File.open call inside a while outfifo == nil.  But that 
> didn't work either.  Is there a way in ruby to detect when the outfifo has 
> been opened for reading on the other end?  One way I thought of was for the C 
> process to send a message up the incoming fifo to the ruby process to tell it 
> when the outfifo is ready for opening. But I just want to make sure there 
> isn't an easier and slicker way to do it with ruby.
>
> -Scott


in ruby you must

   spawn c process
   open infifo for reading
   open outfifo for writing

in c you must

   open infifo for writing
   open outfifo for reading

the open in ruby should block until the c process opens the other end (started
previously via fork/exec), the open in c will block until ruby has opened the
other end

for example

   jib:~ > cat b.rb
   ififo = "#{ Process.pid }.i"
   ofifo = "#{ Process.pid }.o"
   `mkfifo #{ ififo }`
   at_exit{ File.unlink ififo }
   `mkfifo #{ ofifo }`
   at_exit{ File.unlink ofifo }

   if fork
     i = open ififo, 'r'
     o = open ofifo, 'w'
     i.sync = true
     o.sync = true
     2.times{ puts i.gets }
     exit
   else
     i = open ififo, 'w'
     o = open ofifo, 'r'
     i.sync = true
     o.sync = true
     2.times{ i.puts Time.now; sleep 2 }
     exit!
   end

   jib:~ > ruby b.rb
   Wed Aug 25 16:42:14 MDT 2004
   Wed Aug 25 16:42:16 MDT 2004



another way

   jib:~ > cat a.rb
   ififo = "#{ Process.pid }.i"
   ofifo = "#{ Process.pid }.o"
   `mkfifo #{ ififo }`
   at_exit{ File.unlink ififo }
   `mkfifo #{ ofifo }`
   at_exit{ File.unlink ofifo }

   i = open ififo, 'r+'
   i.sync = true
   o = open ififo, 'r+'
   o.sync = true

   if fork
     2.times do
       puts i.gets
     end
     exit
   else
     i, o = o, i
     2.times do
       o.puts Time.now
       sleep 2
     end
     exit!
   end

   jib:~ > ruby a.rb
   Wed Aug 25 16:43:04 MDT 2004
   Wed Aug 25 16:43:06 MDT 2004


-a
--
===============================================================================
| EMAIL   :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE   :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it. 
|   --Dogen
===============================================================================