here's something using open4:
require 'tempfile'
require 'open4'
def maim pid, opts = {}
#--{{{
sigs = opts['signals'] || opts[:signals] || %w(SIGTERM SIGQUIT SIGKILL)
suspend = opts['suspend'] || opts[:suspend] || 4
pid = Integer "#{ pid }"
existed = false
sigs.each do |sig|
begin
Process::kill sig, pid
existed = true
rescue Errno::ESRCH
unless existed
return nil
else
return true
end
end
return true unless alive?(pid)
sleep suspend
return true unless alive?(pid)
end
return(not alive?(pid)) #--}}}
end
def alive? pid
#--{{{
pid = Integer "#{ pid }"
begin
Process::kill 0, pid
true
rescue Errno::ESRCH
false
end
#--}}}
end
def popen_sync cmd
#--{{{
tf = Tempfile::new $PROGRAM_NAME
tf.puts <<-ruby_code
STDOUT.sync = STDERR.sync = true
exec STDIN.read
ruby_code
tf.close
sync_cmd = "ruby #{ tf.path }"
pid, stdin, stdout, stderr = Open4::popen4 sync_cmd
stdin.puts cmd
stdin.close
if block_given?
begin
yield [pid, stdout, stderr]
ensure
maim pid
end
else
at_exit{ maim pid rescue nil }
[pid, stdout, stderr]
end
#--}}}
end
output_program = "ruby -e 'loop{ p 42; sleep 5}'"
popen_sync(output_program) do |pid, stdout, stderr|
while(line = stdout.gets)
puts "stdout => <#{ line.strip }>"
STDOUT.flush
end
while(line = stderr.gets)
puts "stderr => <#{ line.strip }>"
STDOUT.flush
end
end
handling stdout and stderr simoultaneously on windows will be tricky though...
see many threads on this list for that.
cheers.
-a
···
On Sat, 13 Aug 2005, Forrest Chang wrote:
"Ara.T.Howard" <Ara.T.Howard@noaa.gov> writes:
Hi Ara:
I tried tweaking your code to use IO.win32_popen3 coz I wanted to
process stderr as well and we're back to the "doesn't look like
stdout/stderr are being flushed". Any additional ideas?
Thanks again
Forrest
--
email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death Like a lamp standing in a strong breeze. --Nagarjuna
===============================================================================