module ImageOptim::Cmd
Helper for running commands
Public Class Methods
capture(cmd)
click to toggle source
Run using backtick Return captured output Will raise SignalException if process was interrupted
# File lib/image_optim/cmd.rb, line 43 def capture(cmd) output = `#{cmd}` check_status! output end
run(*args)
click to toggle source
Run using `system` Return success status Will raise SignalException if process was interrupted
# File lib/image_optim/cmd.rb, line 13 def run(*args) if args.last.is_a?(Hash) && (timeout = args.last.delete(:timeout)) args.last[Gem.win_platform? ? :new_pgroup : :pgroup] = true pid = Process.spawn(*args) waiter = Process.detach(pid) if waiter.join(timeout.to_f) status = waiter.value check_status!(status) status.success? else cleanup(pid, waiter) fail Errors::TimeoutExceeded end else success = system(*args) check_status! success end end
Private Class Methods
check_status!(status = $CHILD_STATUS)
click to toggle source
# File lib/image_optim/cmd.rb, line 53 def check_status!(status = $CHILD_STATUS) return unless status.signaled? # jruby incorrectly returns true for `signaled?` if process exits with # non zero status. For following code # # `sh -c 'exit 66'` # p [$?.signaled?, $?.exitstatus, $?.termsig] # # jruby outputs `[true, 66, 66]` instead of expected `[false, 66, nil]` return if defined?(JRUBY_VERSION) && status.exitstatus == status.termsig fail SignalException, status.termsig end
cleanup(pid, waiter)
click to toggle source
# File lib/image_optim/cmd.rb, line 68 def cleanup(pid, waiter) if Gem.win_platform? kill('KILL', pid) else kill('-TERM', pid) # Allow 10 seconds for the process to exit waiter.join(10) kill('-KILL', pid) end waiter.join end
kill(signal, pid)
click to toggle source
# File lib/image_optim/cmd.rb, line 83 def kill(signal, pid) Process.kill(signal, pid) rescue Errno::ESRCH, Errno::EPERM # expected end