Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -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'] || ''
Expand Down
60 changes: 48 additions & 12 deletions lib/systemu.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
]
Expand Down
15 changes: 15 additions & 0 deletions test/systemu_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down