class SafeExec::PipeExecutor
Constants
- PAGE_SIZE
Public Class Methods
new(stdin, stdout, stderr)
click to toggle source
# File lib/safe_exec/pipe_executor.rb, line 11 def initialize(stdin, stdout, stderr) @stdin, @stdout, @stderr = stdin, stdout, stderr @mutex = Mutex.new end
Public Instance Methods
run(cmd, *args) { |wait_thr| ... }
click to toggle source
# File lib/safe_exec/pipe_executor.rb, line 16 def run(cmd, *args) assert_untainted_command(cmd, *args) @mutex.synchronize do Open3.popen3([cmd, cmd], *args) do |stdin, stdout, stderr, wait_thr| @threads = [ pusher(@stdin, stdin), drainer(stdout, @stdout), drainer(stderr, @stderr) ] @threads.each { |t| t.abort_on_exception = true } yield wait_thr if block_given? wait_thr.value.tap { @threads.each { |t| t.join } } end end end
timeout(seconds, exception = Timeout::Error)
click to toggle source
# File lib/safe_exec/pipe_executor.rb, line 34 def timeout(seconds, exception = Timeout::Error) TimeoutDelegate.new(self, seconds, exception) end
Private Instance Methods
abort()
click to toggle source
# File lib/safe_exec/pipe_executor.rb, line 71 def abort @threads.each { |t| t.kill } end
assert_untainted_command(*components)
click to toggle source
# File lib/safe_exec/pipe_executor.rb, line 65 def assert_untainted_command(*components) components.each do |component| raise SecurityError.new("refusing to construct a command line from tainted component #{component}") if component.tainted? end end
drainer(input, output)
click to toggle source
# File lib/safe_exec/pipe_executor.rb, line 47 def drainer(input, output) Thread.new do stream(input, output) output.flush end end
pusher(input, output)
click to toggle source
# File lib/safe_exec/pipe_executor.rb, line 40 def pusher(input, output) Thread.new do stream(input, output) output.close unless output.closed? end end
stream(input, output)
click to toggle source
# File lib/safe_exec/pipe_executor.rb, line 54 def stream(input, output) until input.closed? page = input.read(PAGE_SIZE) if page output.write(page) else break end end end