diff --git a/Rakefile b/Rakefile index bce655c..c881f1d 100644 --- a/Rakefile +++ b/Rakefile @@ -297,7 +297,7 @@ BEGIN { # discover full path to this ruby executable # - c = Config::CONFIG + c = ::RbConfig::CONFIG bindir = c["bindir"] || c['BINDIR'] ruby_install_name = c['ruby_install_name'] || c['RUBY_INSTALL_NAME'] || 'ruby' ruby_ext = c['EXEEXT'] || '' diff --git a/lib/systemu.rb b/lib/systemu.rb index aa12fe4..4f8bf5c 100644 --- a/lib/systemu.rb +++ b/lib/systemu.rb @@ -50,10 +50,50 @@ def quote(*words) end end + ## + # Class for returning the result of a systemu invocation + # + # This will contain at least a member +status+ containing a Process::Status + # object representing the result of the subprocess invocation. If a block was + # passed for parallel execution in a separate thread, this thread's instance + # object will be stored as member +thread+. + # + # In general this class is intended as a thin wrapper around the + # Process::Status instance it contains. Any access other than to the +thread+ + # member will be forwared to the +status+ object. + class Result + attr_reader(:status) + attr_reader(:thread) + + def initialize(status, thread = nil) + @status = status + @thread = thread + end + + def ==(arg) + case arg + when Integer + @status == arg + when Result + (@status == arg.status) && (@thread == arg.thread) + else + raise "No comparison between SystemU::Result and #{arg.class}" + end + end + + def method_missing(sym, *args) + @status.send(sym, *args) + end + + def to_s + @status.to_s + end + end + + # # instance methods # - def initialize argv, opts = {}, &block getopt = getopts opts @@ -101,17 +141,10 @@ def systemu pipe.read rescue nil end } - status = $? + status = Result.new($?) ensure if thread - begin - class << status - attr 'thread' - end - status.instance_eval{ @thread = thread } - rescue - 42 - end + status = Result.new($?, thread) end end @@ -294,10 +327,13 @@ def systemu field = process.get_class.get_declared_field("pid") field.set_accessible(true) pid = field.get(process) - _thread = new_thread pid, @block if @block + thread = new_thread pid, @block if @block exit_code = process.wait_for [ - RubyProcess::RubyStatus.new_process_status(JRuby.runtime, exit_code, pid), + Result.new( + RubyProcess::RubyStatus.new_process_status(JRuby.runtime, exit_code, pid), + thread + ), stdout.join, stderr.join ] diff --git a/test/systemu_test.rb b/test/systemu_test.rb index 6d4bf2b..078b05a 100644 --- a/test/systemu_test.rb +++ b/test/systemu_test.rb @@ -31,6 +31,21 @@ end end + testing 'invoke systemu with a block' do + res = systemu("sleep 0.1") { puts('Waiting') } + assert { res[1].instance_of?(String) } + assert { res[2].instance_of?(String) } + res = res[0] + assert { (res & 0xFFFF) == 0 } + assert { res == 0 } + assert { res.exited? } + assert { res.exitstatus == 0 } + assert { res.pid.instance_of?(Integer) } + assert { !res.signaled? } + assert { res.success? } + assert { res.to_i == 0 } + assert { res.to_s =~ /^pid \d+ exit 0$/ } + end end