def read_output(stdout, stderr)
require 'thread'
[STDERR, $stderr, stderr, STDOUT, $stdout, stdout].map { |x| x.sync = true }
reads = Queue.new
output = ""
err_t = Thread.new do
while !stderr.eof?
ary = [:stderr, nil, stderr.readline]
ary[1] = Time.now.to_f
reads << ary
Thread.pass
end
end
out_t = Thread.new do
while !stdout.eof?
ary = [:stdout, nil, stdout.read(1)]
ary[1] = Time.now.to_f
reads << ary
Thread.pass
end
end
tty_t = Thread.new do
next_time = nil
while true
while reads.length > 0
cur_reads = [next_time || reads.shift]
time = cur_reads[0][1]
while next_time = reads.shift
break if next_time[1] != time
cur_reads << next_time
end
stderr_reads, stdout_reads = cur_reads.partition { |x| x[0] == :stderr }
(stderr_reads + stdout_reads).each do |rec|
output << rec[2]
print rec[2]
end
end
Thread.pass
end
end
while !stderr.eof? or !stdout.eof? or !reads.empty?
Thread.pass
end
sleep 1
tty_t.kill
puts
return output + "\n"
end