\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /opt/chef.upgrade/embedded/lib/ruby/gems/2.3.0/gems/specinfra-2.68.0/lib/specinfra/backend/

Viewing File: exec.rb

require 'singleton'
require 'fileutils'
require 'shellwords'
require 'sfl'

module Specinfra
  module Backend
    class Exec < Base
      def run_command(cmd, opts={})
        cmd = build_command(cmd)
        cmd = add_pre_command(cmd)
        stdout, stderr, exit_status = with_env do
          spawn_command(cmd)
        end

        if @example
          @example.metadata[:command] = cmd
          @example.metadata[:stdout]  = stdout
        end

        CommandResult.new :stdout => stdout, :stderr => stderr, :exit_status => exit_status
      end

      def send_file(from, to)
        FileUtils.cp(from, to)
      end

      def send_directory(from, to)
        FileUtils.cp_r(from, to)
      end

      def build_command(cmd)
        shell = get_config(:shell) || '/bin/sh'
        cmd = cmd.shelljoin if cmd.is_a?(Array)
        shell = shell.shellescape

        if get_config(:interactive_shell)
          shell << " -i"
        end

        if get_config(:login_shell)
          shell << " -l"
        end

        cmd = "#{shell} -c #{cmd.to_s.shellescape}"

        path = get_config(:path)
        if path
          cmd = %Q{env PATH="#{path}" #{cmd}}
        end

        cmd
      end

      private
      def spawn_command(cmd)
        stdout, stderr = '', ''
        begin
          quit_r, quit_w = IO.pipe
          out_r,  out_w  = IO.pipe
          err_r,  err_w  = IO.pipe

          th = Thread.new do
            output = {
              quit_r => "",
              out_r => "",
              err_r => ""
            }

            handlers = {
              quit_r => nil,
              out_r => @stdout_handler,
              err_r => @stderr_handler
            }

            begin
              loop do
                readable_ios, = IO.select(output.keys)

                readable_ios.each do |fd|
                  loop do
                    begin
                      out = fd.read_nonblock(4096)
                      output[fd] << out

                      handlers[fd].call(out) if handlers[fd]
                    rescue Errno::EAGAIN
                      # Ruby 2.2 has more specific exception class IO::EAGAINWaitReadable
                      break
                    end
                  end
                end

                break unless output[quit_r].empty?
              end
            rescue EOFError
            ensure
              # Consume remained stdout and stderr from buffer
              output.keys.each do |fd|
                loop do
                  begin
                    out = fd.read_nonblock(4096)
                    output[fd] << out

                    handlers[fd].call(out) if handlers[fd]
                  rescue Errno::EAGAIN, EOFError
                    # Ruby 2.2 has more specific exception class IO::EAGAINWaitReadable
                    break
                  end
                end
              end

              stdout = output[out_r]
              stderr = output[err_r]
              quit_r.close unless quit_r.closed?
              out_r.close  unless out_r.closed?
              err_r.close  unless err_r.closed?
            end
          end

          th.abort_on_exception = true

          pid = spawn(cmd, :out => out_w, :err => err_w)

          pid, stats = Process.waitpid2(pid)

          out_w.close
          err_w.close

          begin
            quit_w.syswrite 1
          rescue Errno::EPIPE
          end

          th.value # wait
        ensure
          quit_w.close unless quit_w.closed?
        end

        return stdout, stderr, stats.exitstatus
      end

      def with_env
        keys = %w[BUNDLER_EDITOR BUNDLE_BIN_PATH BUNDLE_GEMFILE
            RUBYOPT GEM_HOME GEM_PATH GEM_CACHE]

        keys.each { |key| ENV["_SPECINFRA_#{key}"] = ENV[key] ; ENV.delete(key) }

        env = get_config(:env) || {}
        env[:LANG] ||= 'C'

        env.each do |key, value|
          key = key.to_s
          ENV["_SPECINFRA_#{key}"] = ENV[key];
          ENV[key] = value
        end

        yield
      ensure
        keys.each { |key| ENV[key] = ENV.delete("_SPECINFRA_#{key}") }
        env.each do |key, value|
          key = key.to_s
          ENV[key] = ENV.delete("_SPECINFRA_#{key}");
        end
      end

      def add_pre_command(cmd)
        if get_config(:pre_command)
          pre_cmd = build_command(get_config(:pre_command))
          "#{pre_cmd} && #{cmd}"
        else
          cmd
        end
      end
    end
  end
end