Thanks so much, Ara. That's almost perfect, except that the exitstatus
seems to be eaten. No matter what happens, I get a clean 0 exitstatus.
For example:

require 'open3'

`lua xxx`
#=> lua: cannot open xxx: No such file or directory

p $?.exitstatus
#=> 1

output, errors = '', ''
p Open3::popen3( "lua xxx" ){ |i,o,e|
	i.close
	o.each { |line| output << line }
	e.each { |line| errors << line }
	$?.exitstatus
}
#=> 0


I can mostly infer the failure based on whether or not messages came to
stderr, but it'd be nice to know for sure.