lib/mini_magick/shell.rb in mini_magick-4.9.0 vs lib/mini_magick/shell.rb in mini_magick-4.9.1
- old
+ new
@@ -36,44 +36,38 @@
private
def execute_open3(command, options = {})
require "open3"
- in_w, out_r, err_r, subprocess_thread = Open3.popen3(*command)
+ # We would ideally use Open3.capture3, but it wouldn't allow us to
+ # terminate the command after timing out.
+ Open3.popen3(*command) do |in_w, out_r, err_r, thread|
+ [in_w, out_r, err_r].each(&:binmode)
+ stdout_reader = Thread.new { out_r.read }
+ stderr_reader = Thread.new { err_r.read }
+ begin
+ in_w.write options[:stdin].to_s
+ rescue Errno::EPIPE
+ end
+ in_w.close
- capture_command(in_w, out_r, err_r, subprocess_thread, options)
+ begin
+ Timeout.timeout(MiniMagick.timeout, nil, "MiniMagick command timed out: #{command}") { thread.join }
+ ensure
+ Process.kill("TERM", thread.pid) rescue nil
+ Process.waitpid(thread.pid) rescue nil
+ end
+
+ [stdout_reader.value, stderr_reader.value, thread.value]
+ end
end
def execute_posix_spawn(command, options = {})
require "posix-spawn"
child = POSIX::Spawn::Child.new(*command, input: options[:stdin].to_s, timeout: MiniMagick.timeout)
[child.out, child.err, child.status]
rescue POSIX::Spawn::TimeoutExceeded
- raise Timeout::Error
- end
-
- def capture_command(in_w, out_r, err_r, subprocess_thread, options)
- [in_w, out_r, err_r].each(&:binmode)
- stdout_reader = Thread.new { out_r.read }
- stderr_reader = Thread.new { err_r.read }
- begin
- in_w.write options[:stdin].to_s
- rescue Errno::EPIPE
- end
- in_w.close
-
- Timeout.timeout(MiniMagick.timeout) { subprocess_thread.join }
-
- [stdout_reader.value, stderr_reader.value, subprocess_thread.value]
- rescue Timeout::Error => error
- begin
- Process.kill("TERM", subprocess_thread.pid)
- rescue Errno::ESRCH
- # ignore if the PID doesn't exist
- end
- raise error
- ensure
- [out_r, err_r].each(&:close)
+ raise Timeout::Error, "MiniMagick command timed out: #{command}"
end
def log(command, &block)
value = nil
duration = Benchmark.realtime { value = block.call }