From a02e1d0c15c7554e37ba21ef598ff2373ff110c8 Mon Sep 17 00:00:00 2001 From: markuspg Date: Thu, 23 Jun 2022 20:06:05 +0200 Subject: [PATCH 1/3] Replace deprecated Config by RbConfig It seems RbConfig was introduced somewhere around Ruby 2.0. So now that Ruby 3.1 is around its predecessor Config should be ready to be dropped. --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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'] || '' From 5d72a9a26d56fa83cff40664c20272cb6b76899a Mon Sep 17 00:00:00 2001 From: markuspg Date: Thu, 23 Jun 2022 23:07:36 +0200 Subject: [PATCH 2/3] Add a test for systemu invocation with a block --- test/systemu_test.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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 From 21a6b0755a07194cdc4ce4559221c5aaefdc2339 Mon Sep 17 00:00:00 2001 From: markuspg Date: Wed, 22 Jun 2022 22:17:15 +0200 Subject: [PATCH 3/3] Attempt to fix Ruby incompatibility --- lib/systemu.rb | 60 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 12 deletions(-) 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 ]