lib/buildbox/command.rb
# The chunk size for reading from subprocess IO.
The chunk size for reading from subprocess IO.
The chunk size for reading from subprocess IO .
def start(&block)
      timeout = @options[:timeout]
      process.cwd = File.expand_path(@options[:directory] || Dir.pwd)
      read_pipe, write_pipe = begin
                                PTY.open
                              rescue
                                IO.pipe
                              end
      process.io.stdout     = write_pipe
      process.io.stderr     = write_pipe
      process.duplex        = true
      if @options[:environment]
        @options[:environment].each_pair do |key, value|
          process.environment[key] = value
        end
      end
      process.start
      process.io.stdin.sync = true
      @logger.debug("Process #{arguments} started with PID: #{process.pid}")
      if RUBY_PLATFORM != "java"
        write_pipe.close
      end
      start_time = Time.now.to_i
      output = ""
      @logger.debug("Selecting on IO")
      while true
        results = IO.select([read_pipe], nil, nil, timeout || 0.1) || []
        readers = results[0]
        raise TimeoutExceeded if timeout && (Time.now.to_i - start_time) > timeout
        if readers && !readers.empty?
          readers.each do |r|
            data = read_io(r)
            next if data.empty?
            output << cleaned_data = UTF8.clean(data)
            yield cleaned_data if block_given?
          end
        end
        break if process.exited?
      end
      begin
        remaining = (timeout || 32000) - (Time.now.to_i - start_time)
        remaining = 0 if remaining < 0
        @logger.debug("Waiting for process to exit. Remaining to timeout: #{remaining}")
        process.poll_for_exit(remaining)
      rescue ChildProcess::TimeoutError
        raise TimeoutExceeded
      end
      @logger.debug("Exit status: #{process.exit_code}")
      extra_data = read_io(read_pipe)
      if extra_data != ""
        output << cleaned_data = UTF8.clean(extra_data)
        yield cleaned_data if block_given?
      end
      if RUBY_PLATFORM == "java"
        write_pipe.close
      end
      @output      = output.chomp
      @exit_status = process.exit_code
    end
def start ( & block ) timeout = @options [ :timeout ] process . cwd = File . expand_path ( @options [ :directory ] || Dir . pwd ) read_pipe , write_pipe = begin PTY . open rescue IO . pipe end process . io . stdout = write_pipe process . io . stderr = write_pipe process . duplex = true if @options [ :environment ] @options [ :environment ] . each_pair do | key , value | process . environment [ key ] = value end end process . start process . io . stdin . sync = true @logger . debug ( "Process #{arguments} started with PID: #{process.pid}" ) if RUBY_PLATFORM != "java" write_pipe . close end start_time = Time . now . to_i output = "" @logger . debug ( "Selecting on IO" ) while true results = IO . select ( [ read_pipe ] , nil , nil , timeout || 0.1 ) || [ ] readers = results [ 0 ] raise TimeoutExceeded if timeout && ( Time . now . to_i - start_time ) > timeout if readers && ! readers . empty? readers . each do | r | data = read_io ( r ) next if data . empty? output << cleaned_data = UTF8 . clean ( data ) yield cleaned_data if block_given? end end break if process . exited? end begin remaining = ( timeout || 32000 ) - ( Time . now . to_i - start_time ) remaining = 0 if remaining < 0 @logger . debug ( "Waiting for process to exit. Remaining to timeout: #{remaining}" ) process . poll_for_exit ( remaining ) rescue ChildProcess :: TimeoutError raise TimeoutExceeded end @logger . debug ( "Exit status: #{process.exit_code}" ) extra_data = read_io ( read_pipe ) if extra_data != "" output << cleaned_data = UTF8 . clean ( extra_data ) yield cleaned_data if block_given? end if RUBY_PLATFORM == "java" write_pipe . close end @output = output . chomp @exit_status = process . exit_code end
The chunk size for reading from subprocess IO.
The chunk size for reading from subprocess IO .
# Get the timeout, if we have one # Set the directory for the process # Create the pipes so we can read the output in real time. PTY # isn't avaible on all platforms (heroku) so we just fallback to IO.pipe # if it's not presetnt. # Set the environment on the process # Start the process # Make sure the stdin does not buffer # On Java, we have to close after. See down the method... # Otherwise, we close the writer right here, since we're # not on the writing side. # Record the start time for timeout purposes # Track the output as it goes # Check if we have exceeded our timeout # Kill the process and wait a bit for it to disappear # Process.kill('KILL', process.pid) # Process.waitpid2(process.pid) # Check the readers to see if they're ready # Read from the IO object # We don't need to do anything if the data is empty # Break out if the process exited. We have to do this before # attempting to write to stdin otherwise we'll get a broken pipe # error. # Wait for the process to end. # Read the final output data, since it is possible we missed a small # amount of text between the time we last read data and when the # process exited. # Read the extra data # If there's some that we missed # On JRuby, we need to close the writers after the process, # for some reason. See https://github.com/mitchellh/vagrant/pull/711
block