def execmd(*args)
i = 0
if i < args.size
if args[i].kind_of?(Hash)
env = args[i]
i += 1
else
env = Hash[]
end
end
if i < args.size
if args[i].kind_of?(Array)
args2 = args[i]
else
args2 = [ args[i] ]
end
program = args2[0]
i += 1
else
raise ArgumentError.new("missing argument: cmd")
end
if i < args.size
if args[i].kind_of?(Hash)
opts = Hash[args[i].map {|k,v| [k.to_sym, v]} ]
i += 1
end
else
opts = Hash[]
end
opts[:process] = false unless opts.include?(:process)
opts[:stdin] = true unless opts.include?(:stdin)
opts[:stdout] = true unless opts.include?(:stdout)
opts[:stderr] = true unless opts.include?(:stderr)
if !program.include?("/") and !program_in_path?(program)
raise ExecutableNotFound.new(program)
end
logger.debug("Running command", :args => args2)
stdout_r, stdout_w = IO.pipe
stderr_r, stderr_w = IO.pipe
process = ChildProcess.build(*args2)
process.environment.merge!(env)
process.io.stdout = stdout_w
process.io.stderr = stderr_w
if block_given? and opts[:stdin]
process.duplex = true
end
process.start
stdout_w.close; stderr_w.close
logger.debug("Process is running", :pid => process.pid)
if block_given?
args3 = []
args3.push(process) if opts[:process]
args3.push(process.io.stdin) if opts[:stdin]
args3.push(stdout_r) if opts[:stdout]
args3.push(stderr_r) if opts[:stderr]
yield(*args3)
process.io.stdin.close if opts[:stdin] and not process.io.stdin.closed?
stdout_r.close unless stdout_r.closed?
stderr_r.close unless stderr_r.closed?
else
logger.pipe(stdout_r => :info, stderr_r => :info)
end
process.wait if process.alive?
return process.exit_code
end