def systemu
tmpdir do |tmp|
c = child_setup tmp
status = nil
begin
thread = nil
quietly{
IO.popen "#{ quote(@ruby) } #{ quote(c['program']) }", 'r+' do |pipe|
line = pipe.gets
case line
when %r/^pid: \d+$/
cid = Integer line[%r/\d+/]
else
begin
buf = pipe.read
buf = "#{ line }#{ buf }"
e = Marshal.load buf
raise unless Exception === e
raise e
rescue
raise "wtf?\n#{ buf }\n"
end
end
thread = new_thread cid, @block if @block
pipe.read rescue nil
end
}
status = $?
ensure
if thread
begin
class << status
attr 'thread'
end
status.instance_eval{ @thread = thread }
rescue
42
end
end
end
if @stdout or @stderr
open(c['stdout']){|f| relay f => @stdout} if @stdout
open(c['stderr']){|f| relay f => @stderr} if @stderr
status
else
[status, IO.read(c['stdout']), IO.read(c['stderr'])]
end
end
end