# File lib/chef/shell_out/unix.rb, line 16
      def run_command
        @child_pid = fork_subprocess

        configure_parent_process_file_descriptors
        propagate_pre_exec_failure

        @result = nil
        @execution_time = 0

        # Ruby 1.8.7 and 1.8.6 from mid 2009 try to allocate objects during GC
        # when calling IO.select and IO#read. Some OS Vendors are not interested
        # in updating their ruby packages (Apple, *cough*) and we *have to*
        # make it work. So I give you this epic hack:
        GC.disable
        until @status
          ready = IO.select(open_pipes, nil, nil, READ_WAIT_TIME)
          unless ready
            @execution_time += READ_WAIT_TIME
            if @execution_time >= timeout && !@result
              raise Chef::Exceptions::CommandTimeout, "command timed out:\n#{format_for_exception}"
            end
          end

          if ready && ready.first.include?(child_stdout)
            read_stdout_to_buffer
          end
          if ready && ready.first.include?(child_stderr)
            read_stderr_to_buffer
          end

          unless @status
            # make one more pass to get the last of the output after the
            # child process dies
            if results = Process.waitpid2(@child_pid, Process::WNOHANG)
              @status = results.last
              redo
            end
          end
        end
        self
      rescue Exception
        # do our best to kill zombies
        Process.waitpid2(@child_pid, Process::WNOHANG) rescue nil
        raise
      ensure
        # no matter what happens, turn the GC back on, and hope whatever busted
        # version of ruby we're on doesn't allocate some objects during the next
        # GC run.
        GC.enable
        close_all_pipes
      end