root/lib/proxy/util.rb @ 7e3ca5c2
20618e98 | Lukas Zapletal | require 'open3'
|
|
216728d0 | Sam Kottler | require 'shellwords'
|
|
20618e98 | Lukas Zapletal | ||
e09de9d9 | Ohad Levy | module Proxy::Util
|
|
20618e98 | Lukas Zapletal | ||
class CommandTask
|
|||
include Proxy::Log
|
|||
# track all threads in the class variable
|
|||
@@tasks = []
|
|||
# create new task and spawn new thread logging all the cmd
|
|||
# output to the proxy log. only the process' output is connected
|
|||
# stderr is redirected to proxy error log, stdout to proxy debug log
|
|||
def initialize(cmd)
|
|||
# clean finished tasks from the array
|
|||
@@tasks = @@tasks.collect { |t| nil unless t.is_a? String }.compact
|
|||
# run the task in its own thread
|
|||
68bfe266 | Ohad Levy | logger.debug "Starting task (total: #{@@tasks.size}): #{cmd}"
|
|
20618e98 | Lukas Zapletal | @task = Thread.new(cmd) do |cmd|
|
|
Open3::popen3(cmd) do |stdin,stdout,stderr,thr|
|
|||
# PIDs are not available under Ruby 1.8
|
|||
pid = thr.nil? ? rand(9999) : thr.pid
|
|||
stdout.each do |line|
|
|||
logger.debug "[#{pid}] #{line}"
|
|||
end
|
|||
stderr.each do |line|
|
|||
logger.error "[#{pid}] #{line}"
|
|||
end
|
|||
end
|
|||
$?
|
|||
end
|
|||
@@tasks << @task
|
|||
end
|
|||
# wait for the task to finish and get the subprocess return code
|
|||
def join
|
|||
@task.value
|
|||
end
|
|||
# wait for all tasks to finish
|
|||
def self.join_all
|
|||
@@tasks.each { |aThread| aThread.join }
|
|||
end
|
|||
end
|
|||
4156b933 | Ohad Levy | # searches for binaries in predefined directories and user PATH
|
|
e09de9d9 | Ohad Levy | # accepts a binary name and an array of paths to search first
|
|
c6ea383c | Paul kelly | # if path is omitted will search only in user PATH
|
|
e09de9d9 | Ohad Levy | def which(bin, *path)
|
|
7e3ca5c2 | Michael Moll | path = path + ['/usr/bin', '/usr/sbin', '/usr/local/bin', '/usr/local/sbin']
|
|
e09de9d9 | Ohad Levy | path += ENV['PATH'].split(File::PATH_SEPARATOR)
|
|
308be2fc | Frank Sweetser | path.flatten.uniq.each do |dir|
|
|
e09de9d9 | Ohad Levy | dest = File.join(dir, bin)
|
|
return dest if FileTest.file? dest and FileTest.executable? dest
|
|||
end
|
|||
return false
|
|||
rescue StandardError => e
|
|||
logger.warn e
|
|||
return false
|
|||
end
|
|||
216728d0 | Sam Kottler | ||
4a8411d8 | Dmitri Dolguikh | def escape_for_shell(command)
|
|
216728d0 | Sam Kottler | # This is a backport for using the core Shellwords#escape that's in 1.9.2
|
|
# when using 1.8.7.
|
|||
if RUBY_VERSION < '1.9.2'
|
|||
return command.shellescape if command.respond_to? :shellescape
|
|||
# An empty argument will be skipped, so return empty quotes.
|
|||
return "''" if command.empty?
|
|||
command = command.dup
|
|||
# Process as a single byte sequence because not all shell
|
|||
# implementations are multibyte aware.
|
|||
command.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
|
|||
command.gsub!(/\n/, "'\n'")
|
|||
return command
|
|||
else
|
|||
Shellwords.escape(command)
|
|||
end
|
|||
end
|
|||
e09de9d9 | Ohad Levy | end
|