lib/frontkick/command.rb in frontkick-0.5.0 vs lib/frontkick/command.rb in frontkick-0.5.1
- old
+ new
@@ -2,11 +2,11 @@
require 'open3'
require 'shellwords'
module Frontkick
class Command
- def self.exec(cmd, opts = {})
+ def self.exec(cmd, opts = {}, &block)
opts[:timeout_kill] = true unless opts.has_key?(:timeout_kill) # default: true
exit_code, duration = nil
stdin, stdout, stderr, wait_thr, pid = nil
@@ -37,42 +37,40 @@
if opts[:dry_run]
return Result.new(:stdout => command, :stderr => '', :exit_code => 0, :duration => 0)
end
- spawn_opts = self.spawn_opts(opts)
+ popen3_opts = self.popen3_opts(opts)
lock_fd = file_lock(opts[:exclusive], opts[:exclusive_blocking]) if opts[:exclusive]
begin
::Timeout.timeout(opts[:timeout], Frontkick::TimeoutLocal) do # nil is for no timeout
duration = Benchmark.realtime do
- stdin, stdout, stderr, wait_thr = Open3.popen3(*cmd_array, spawn_opts)
- out_thread = Thread.new {
+ stdin, stdout, stderr, wait_thr = Open3.popen3(*cmd_array, popen3_opts)
+ out_thr = Thread.new {
begin
while true
out.write stdout.readpartial(4096)
end
rescue EOFError
end
}
- err_thread = Thread.new {
+ err_thr = Thread.new {
begin
while true
err.write stderr.readpartial(4096)
end
rescue EOFError
end
}
stdin.close
pid = wait_thr.pid
- if opts[:kill_child]
- trap_signal(pid)
- end
+ yield(wait_thr) if block_given?
- out_thread.join
- err_thread.join
+ out_thr.join
+ err_thr.join
exit_code = wait_thr.value.exitstatus
process_wait(pid)
end
end
rescue Frontkick::TimeoutLocal => e
@@ -103,30 +101,18 @@
)
end
# private
- def self.spawn_opts(opts)
+ def self.popen3_opts(opts)
opts.dup.tap {|o|
o.delete(:timeout_kill)
o.delete(:exclusive)
o.delete(:exclusive_blocking)
o.delete(:timeout)
- o.delete(:kill_child)
+ o.delete(:out)
+ o.delete(:err)
}
- end
-
- def self.trap_signal(pid)
- trap :INT do
- Process.kill(:TERM, pid)
- process_wait(pid)
- exit 130
- end
- trap :TERM do
- Process.kill(:TERM, pid)
- process_wait(pid)
- exit 143
- end
end
def self.process_wait(pid)
begin
pid, status = Process.waitpid2(pid) # wait child processes finish