Open Fifo for Writing

S

Scott Rubin

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
 
Y

Yohanes Santoso

Scott Rubin said:
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.

Another way would be to poll for writability.

Yet another way: looking at your example, the cprocess is started from
the rubyprocess and communication between the two ensue afterwards. I
can't tell for sure, but it seems the lifetime of the cprocess is
within the lifetime of the invoking rubyprocess. I also do not know if
using fifo is a requirement.

If using fifo is not a requirement, then you may consider using
socketpair (Socket#pair), the modern (arguably) way of setting up
two-way communication channel between parent-child processes.

YS.
 
A

Ara.T.Howard

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
===============================================================================
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top