childprocess 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +2 -1
- data/README.md +15 -3
- data/lib/childprocess/abstract_process.rb +14 -0
- data/lib/childprocess/errors.rb +1 -0
- data/lib/childprocess/jruby.rb +1 -1
- data/lib/childprocess/jruby/process.rb +32 -8
- data/lib/childprocess/jruby/pump.rb +51 -0
- data/lib/childprocess/unix/process.rb +22 -13
- data/lib/childprocess/version.rb +1 -1
- data/lib/childprocess/windows/functions.rb +4 -1
- data/lib/childprocess/windows/process.rb +6 -3
- data/spec/childprocess_spec.rb +30 -13
- data/spec/pid_behavior.rb +1 -1
- data/spec/spec_helper.rb +17 -0
- metadata +5 -5
- data/lib/childprocess/jruby/redirector.rb +0 -29
    
        data/.travis.yml
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -14,18 +14,30 @@ Usage | |
| 14 14 | 
             
            ```ruby
         | 
| 15 15 | 
             
            process = ChildProcess.build("ruby", "-e", "sleep")
         | 
| 16 16 |  | 
| 17 | 
            -
            # inherit stdout/stderr from parent
         | 
| 17 | 
            +
            # inherit stdout/stderr from parent...
         | 
| 18 18 | 
             
            process.io.inherit!
         | 
| 19 19 |  | 
| 20 | 
            -
            # or pass an IO
         | 
| 20 | 
            +
            # ...or pass an IO
         | 
| 21 21 | 
             
            process.io.stdout = Tempfile.new("child-output")
         | 
| 22 22 |  | 
| 23 | 
            +
            # start the process
         | 
| 24 | 
            +
             | 
| 23 25 | 
             
            process.start
         | 
| 24 26 |  | 
| 27 | 
            +
            # check process status
         | 
| 25 28 | 
             
            process.alive?    #=> true
         | 
| 26 29 | 
             
            process.exited?   #=> false
         | 
| 27 30 |  | 
| 28 | 
            -
            process | 
| 31 | 
            +
            # wait indefinitely for process to exit...
         | 
| 32 | 
            +
            process.wait
         | 
| 33 | 
            +
            process.exited?   #=> true
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            # ...or poll for exit + force quit
         | 
| 36 | 
            +
            begin
         | 
| 37 | 
            +
              process.poll_for_exit(10)
         | 
| 38 | 
            +
            rescue ChildProcess::TimeoutError
         | 
| 39 | 
            +
              process.stop # tries increasingly harsher methods to kill the process.
         | 
| 40 | 
            +
            end
         | 
| 29 41 | 
             
            ```
         | 
| 30 42 |  | 
| 31 43 | 
             
            The object returned from ChildProcess.build will implement ChildProcess::AbstractProcess.
         | 
| @@ -44,6 +44,10 @@ module ChildProcess | |
| 44 44 | 
             
                  raise SubclassResponsibility, "io"
         | 
| 45 45 | 
             
                end
         | 
| 46 46 |  | 
| 47 | 
            +
                #
         | 
| 48 | 
            +
                # @return [Fixnum] the pid of the process after it has started
         | 
| 49 | 
            +
                #
         | 
| 50 | 
            +
             | 
| 47 51 | 
             
                def pid
         | 
| 48 52 | 
             
                  raise SubclassResponsibility, "pid"
         | 
| 49 53 | 
             
                end
         | 
| @@ -71,6 +75,16 @@ module ChildProcess | |
| 71 75 | 
             
                  raise SubclassResponsibility, "stop"
         | 
| 72 76 | 
             
                end
         | 
| 73 77 |  | 
| 78 | 
            +
                #
         | 
| 79 | 
            +
                # Block until the process has been terminated.
         | 
| 80 | 
            +
                #
         | 
| 81 | 
            +
                # @return [Fixnum] The exit status of the process
         | 
| 82 | 
            +
                #
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                def wait
         | 
| 85 | 
            +
                  raise SubclassResponsibility, "wait"
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 74 88 | 
             
                #
         | 
| 75 89 | 
             
                # Did the process exit?
         | 
| 76 90 | 
             
                #
         | 
    
        data/lib/childprocess/errors.rb
    CHANGED
    
    
    
        data/lib/childprocess/jruby.rb
    CHANGED
    
    
| @@ -3,6 +3,12 @@ require "java" | |
| 3 3 | 
             
            module ChildProcess
         | 
| 4 4 | 
             
              module JRuby
         | 
| 5 5 | 
             
                class Process < AbstractProcess
         | 
| 6 | 
            +
                  def initialize(args)
         | 
| 7 | 
            +
                    super(args)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    @pumps = []
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 6 12 | 
             
                  def io
         | 
| 7 13 | 
             
                    @io ||= JRuby::IO.new
         | 
| 8 14 | 
             
                  end
         | 
| @@ -12,6 +18,8 @@ module ChildProcess | |
| 12 18 |  | 
| 13 19 | 
             
                    assert_started
         | 
| 14 20 | 
             
                    @exit_code = @process.exitValue
         | 
| 21 | 
            +
                    stop_pumps
         | 
| 22 | 
            +
             | 
| 15 23 | 
             
                    true
         | 
| 16 24 | 
             
                  rescue java.lang.IllegalThreadStateException
         | 
| 17 25 | 
             
                    false
         | 
| @@ -23,8 +31,13 @@ module ChildProcess | |
| 23 31 | 
             
                    assert_started
         | 
| 24 32 |  | 
| 25 33 | 
             
                    @process.destroy
         | 
| 26 | 
            -
                     | 
| 34 | 
            +
                    wait # no way to actually use the timeout here..
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  def wait
         | 
| 38 | 
            +
                    @process.waitFor
         | 
| 27 39 |  | 
| 40 | 
            +
                    stop_pumps
         | 
| 28 41 | 
             
                    @exit_code = @process.exitValue
         | 
| 29 42 | 
             
                  end
         | 
| 30 43 |  | 
| @@ -37,7 +50,7 @@ module ChildProcess | |
| 37 50 | 
             
                  #
         | 
| 38 51 | 
             
                  def pid
         | 
| 39 52 | 
             
                    if @process.getClass.getName != "java.lang.UNIXProcess"
         | 
| 40 | 
            -
                      raise NotImplementedError | 
| 53 | 
            +
                      raise NotImplementedError, "pid is only supported by JRuby child processes on Unix"
         | 
| 41 54 | 
             
                    end
         | 
| 42 55 |  | 
| 43 56 | 
             
                    # About the best way we can do this is with a nasty reflection-based impl
         | 
| @@ -56,21 +69,29 @@ module ChildProcess | |
| 56 69 | 
             
                    pb.directory java.io.File.new(Dir.pwd)
         | 
| 57 70 | 
             
                    set_env pb.environment
         | 
| 58 71 |  | 
| 59 | 
            -
                     | 
| 72 | 
            +
                    begin
         | 
| 73 | 
            +
                      @process = pb.start
         | 
| 74 | 
            +
                    rescue java.io.IOException => ex
         | 
| 75 | 
            +
                      raise LaunchError, ex.message
         | 
| 76 | 
            +
                    end
         | 
| 77 | 
            +
             | 
| 60 78 | 
             
                    setup_io
         | 
| 61 79 | 
             
                  end
         | 
| 62 80 |  | 
| 63 81 | 
             
                  def setup_io
         | 
| 64 82 | 
             
                    if @io
         | 
| 65 | 
            -
                      redirect | 
| 66 | 
            -
                      redirect | 
| 83 | 
            +
                      @pumps << redirect(@process.getErrorStream, @io.stderr)
         | 
| 84 | 
            +
                      @pumps << redirect(@process.getInputStream, @io.stdout)
         | 
| 67 85 | 
             
                    else
         | 
| 68 86 | 
             
                      @process.getErrorStream.close
         | 
| 69 87 | 
             
                      @process.getInputStream.close
         | 
| 70 88 | 
             
                    end
         | 
| 71 89 |  | 
| 72 90 | 
             
                    if duplex?
         | 
| 73 | 
            -
                       | 
| 91 | 
            +
                      stdin = @process.getOutputStream.to_io
         | 
| 92 | 
            +
                      stdin.sync = true
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                      io._stdin = stdin
         | 
| 74 95 | 
             
                    else
         | 
| 75 96 | 
             
                      @process.getOutputStream.close
         | 
| 76 97 | 
             
                    end
         | 
| @@ -82,8 +103,11 @@ module ChildProcess | |
| 82 103 | 
             
                      return
         | 
| 83 104 | 
             
                    end
         | 
| 84 105 |  | 
| 85 | 
            -
                     | 
| 86 | 
            -
             | 
| 106 | 
            +
                    Pump.new(input, output.to_outputstream).run
         | 
| 107 | 
            +
                  end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                  def stop_pumps
         | 
| 110 | 
            +
                    @pumps.each { |pump| pump.stop }
         | 
| 87 111 | 
             
                  end
         | 
| 88 112 |  | 
| 89 113 | 
             
                  def set_env(env)
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            module ChildProcess
         | 
| 2 | 
            +
              module JRuby
         | 
| 3 | 
            +
                class Pump
         | 
| 4 | 
            +
                  BUFFER_SIZE = 2048
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def initialize(input, output)
         | 
| 7 | 
            +
                    @input  = input
         | 
| 8 | 
            +
                    @output = output
         | 
| 9 | 
            +
                    @stop   = false
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  def stop
         | 
| 13 | 
            +
                    @stop = true
         | 
| 14 | 
            +
                    @thread && @thread.join
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def run
         | 
| 18 | 
            +
                    @thread = Thread.new { pump }
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    self
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  private
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  def pump
         | 
| 26 | 
            +
                    buffer = Java.byte[BUFFER_SIZE].new
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    until @stop
         | 
| 29 | 
            +
                      read, avail = 0, 0
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                      while read != -1
         | 
| 32 | 
            +
                        avail = [@input.available, 1].max
         | 
| 33 | 
            +
                        read = @input.read(buffer, 0, avail)
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                        if read > 0
         | 
| 36 | 
            +
                          @output.write(buffer, 0, read)
         | 
| 37 | 
            +
                          @output.flush
         | 
| 38 | 
            +
                        end
         | 
| 39 | 
            +
                      end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                      sleep 0.1
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    @output.flush
         | 
| 45 | 
            +
                  rescue java.io.IOException => ex
         | 
| 46 | 
            +
                    $stderr.puts ex.message, ex.backtrace if $DEBUG
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                end # Pump
         | 
| 50 | 
            +
              end # JRuby
         | 
| 51 | 
            +
            end # ChildProcess
         | 
| @@ -1,9 +1,6 @@ | |
| 1 1 | 
             
            module ChildProcess
         | 
| 2 2 | 
             
              module Unix
         | 
| 3 3 | 
             
                class Process < AbstractProcess
         | 
| 4 | 
            -
                  #
         | 
| 5 | 
            -
                  # @return [Fixnum] the pid of the process after it has started
         | 
| 6 | 
            -
                  #
         | 
| 7 4 | 
             
                  attr_reader :pid
         | 
| 8 5 |  | 
| 9 6 | 
             
                  def io
         | 
| @@ -28,12 +25,6 @@ module ChildProcess | |
| 28 25 | 
             
                    true
         | 
| 29 26 | 
             
                  end
         | 
| 30 27 |  | 
| 31 | 
            -
                  #
         | 
| 32 | 
            -
                  # Did the process exit?
         | 
| 33 | 
            -
                  #
         | 
| 34 | 
            -
                  # @return [Boolean]
         | 
| 35 | 
            -
                  #
         | 
| 36 | 
            -
             | 
| 37 28 | 
             
                  def exited?
         | 
| 38 29 | 
             
                    return true if @exit_code
         | 
| 39 30 |  | 
| @@ -49,12 +40,14 @@ module ChildProcess | |
| 49 40 | 
             
                    !!pid
         | 
| 50 41 | 
             
                  end
         | 
| 51 42 |  | 
| 52 | 
            -
                  private
         | 
| 53 | 
            -
             | 
| 54 43 | 
             
                  def wait
         | 
| 55 | 
            -
                     | 
| 44 | 
            +
                    pid, status = ::Process.waitpid2 @pid
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    @exit_code = status.exitstatus || status.termsig
         | 
| 56 47 | 
             
                  end
         | 
| 57 48 |  | 
| 49 | 
            +
                  private
         | 
| 50 | 
            +
             | 
| 58 51 | 
             
                  def send_term
         | 
| 59 52 | 
             
                    send_signal 'TERM'
         | 
| 60 53 | 
             
                  end
         | 
| @@ -76,11 +69,16 @@ module ChildProcess | |
| 76 69 | 
             
                      stderr = @io.stderr
         | 
| 77 70 | 
             
                    end
         | 
| 78 71 |  | 
| 72 | 
            +
                    # pipe used to detect exec() failure
         | 
| 73 | 
            +
                    exec_r, exec_w = ::IO.pipe
         | 
| 74 | 
            +
                    ChildProcess.close_on_exec exec_w
         | 
| 75 | 
            +
             | 
| 79 76 | 
             
                    if duplex?
         | 
| 80 77 | 
             
                      reader, writer = ::IO.pipe
         | 
| 81 78 | 
             
                    end
         | 
| 82 79 |  | 
| 83 80 | 
             
                    @pid = fork {
         | 
| 81 | 
            +
                      exec_r.close
         | 
| 84 82 | 
             
                      set_env
         | 
| 85 83 |  | 
| 86 84 | 
             
                      STDOUT.reopen(stdout || "/dev/null")
         | 
| @@ -91,14 +89,25 @@ module ChildProcess | |
| 91 89 | 
             
                        writer.close
         | 
| 92 90 | 
             
                      end
         | 
| 93 91 |  | 
| 94 | 
            -
                       | 
| 92 | 
            +
                      begin
         | 
| 93 | 
            +
                        exec(*@args)
         | 
| 94 | 
            +
                      rescue SystemCallError => ex
         | 
| 95 | 
            +
                        exec_w << ex.message
         | 
| 96 | 
            +
                      end
         | 
| 95 97 | 
             
                    }
         | 
| 96 98 |  | 
| 99 | 
            +
                    exec_w.close
         | 
| 100 | 
            +
             | 
| 97 101 | 
             
                    if duplex?
         | 
| 98 102 | 
             
                      io._stdin = writer
         | 
| 99 103 | 
             
                      reader.close
         | 
| 100 104 | 
             
                    end
         | 
| 101 105 |  | 
| 106 | 
            +
                    # if we don't eventually get EOF, exec() failed
         | 
| 107 | 
            +
                    unless exec_r.eof?
         | 
| 108 | 
            +
                      raise LaunchError, exec_r.read || "executing command with #{@args.inspect} failed"
         | 
| 109 | 
            +
                    end
         | 
| 110 | 
            +
             | 
| 102 111 | 
             
                    ::Process.detach(@pid) if detach?
         | 
| 103 112 | 
             
                  end
         | 
| 104 113 |  | 
    
        data/lib/childprocess/version.rb
    CHANGED
    
    
| @@ -34,6 +34,9 @@ module ChildProcess | |
| 34 34 | 
             
                      read_pipe = read_pipe_ptr.read_pointer
         | 
| 35 35 | 
             
                      write_pipe = write_pipe_ptr.read_pointer
         | 
| 36 36 |  | 
| 37 | 
            +
                      ok = set_handle_information(write_pipe.address, HANDLE_FLAG_INHERIT, 0)
         | 
| 38 | 
            +
                      ok or raise Error, last_error_message
         | 
| 39 | 
            +
             | 
| 37 40 | 
             
                      si[:hStdInput] = read_pipe
         | 
| 38 41 | 
             
                    end
         | 
| 39 42 |  | 
| @@ -50,7 +53,7 @@ module ChildProcess | |
| 50 53 | 
             
                      pi        # process info
         | 
| 51 54 | 
             
                    )
         | 
| 52 55 |  | 
| 53 | 
            -
                    ok or raise  | 
| 56 | 
            +
                    ok or raise LaunchError, last_error_message
         | 
| 54 57 |  | 
| 55 58 | 
             
                    close_handle pi[:hProcess]
         | 
| 56 59 | 
             
                    close_handle pi[:hThread]
         | 
| @@ -1,9 +1,7 @@ | |
| 1 1 | 
             
            module ChildProcess
         | 
| 2 2 | 
             
              module Windows
         | 
| 3 3 | 
             
                class Process < AbstractProcess
         | 
| 4 | 
            -
             | 
| 5 | 
            -
                  # @return [Fixnum] the pid of the process after it has started
         | 
| 6 | 
            -
                  #
         | 
| 4 | 
            +
             | 
| 7 5 | 
             
                  attr_reader :pid
         | 
| 8 6 |  | 
| 9 7 | 
             
                  def io
         | 
| @@ -22,6 +20,11 @@ module ChildProcess | |
| 22 20 | 
             
                    @handle.close
         | 
| 23 21 | 
             
                  end
         | 
| 24 22 |  | 
| 23 | 
            +
                  def wait
         | 
| 24 | 
            +
                    @handle.wait
         | 
| 25 | 
            +
                    @exit_code = @handle.exit_code
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 25 28 | 
             
                  def exited?
         | 
| 26 29 | 
             
                    return true if @exit_code
         | 
| 27 30 | 
             
                    assert_started
         | 
    
        data/spec/childprocess_spec.rb
    CHANGED
    
    | @@ -13,20 +13,32 @@ describe ChildProcess do | |
| 13 13 | 
             
                process.should be_started
         | 
| 14 14 | 
             
              end
         | 
| 15 15 |  | 
| 16 | 
            +
              it "raises ChildProcess::LaunchError if the process can't be started" do
         | 
| 17 | 
            +
                lambda { invalid_process.start }.should raise_error(ChildProcess::LaunchError)
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 16 20 | 
             
              it "knows if the process crashed" do
         | 
| 17 21 | 
             
                process = exit_with(1).start
         | 
| 18 | 
            -
                process. | 
| 22 | 
            +
                process.wait
         | 
| 19 23 |  | 
| 20 24 | 
             
                process.should be_crashed
         | 
| 21 25 | 
             
              end
         | 
| 22 26 |  | 
| 23 27 | 
             
              it "knows if the process didn't crash" do
         | 
| 24 28 | 
             
                process = exit_with(0).start
         | 
| 25 | 
            -
                process. | 
| 29 | 
            +
                process.wait
         | 
| 26 30 |  | 
| 27 31 | 
             
                process.should_not be_crashed
         | 
| 28 32 | 
             
              end
         | 
| 29 33 |  | 
| 34 | 
            +
              it "can wait for a process to finish" do
         | 
| 35 | 
            +
                process = exit_with(0).start
         | 
| 36 | 
            +
                return_value = process.wait
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                process.should_not be_alive
         | 
| 39 | 
            +
                return_value.should == 0
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 30 42 | 
             
              it "escalates if TERM is ignored" do
         | 
| 31 43 | 
             
                process = ignored('TERM').start
         | 
| 32 44 | 
             
                process.stop
         | 
| @@ -42,7 +54,7 @@ describe ChildProcess do | |
| 42 54 | 
             
                Tempfile.open("env-spec") do |file|
         | 
| 43 55 | 
             
                  with_env('INHERITED' => 'yes') do
         | 
| 44 56 | 
             
                    process = write_env(file.path).start
         | 
| 45 | 
            -
                    process. | 
| 57 | 
            +
                    process.wait
         | 
| 46 58 | 
             
                  end
         | 
| 47 59 |  | 
| 48 60 | 
             
                  file.rewind
         | 
| @@ -59,7 +71,7 @@ describe ChildProcess do | |
| 59 71 |  | 
| 60 72 | 
             
                  ENV['CHILD_ONLY'].should be_nil
         | 
| 61 73 |  | 
| 62 | 
            -
                  process. | 
| 74 | 
            +
                  process.wait
         | 
| 63 75 | 
             
                  file.rewind
         | 
| 64 76 |  | 
| 65 77 | 
             
                  child_env = eval(file.read)
         | 
| @@ -74,7 +86,8 @@ describe ChildProcess do | |
| 74 86 | 
             
                    process.environment['CHILD_ONLY'] = 'yes'
         | 
| 75 87 |  | 
| 76 88 | 
             
                    process.start
         | 
| 77 | 
            -
                    process. | 
| 89 | 
            +
                    process.wait
         | 
| 90 | 
            +
             | 
| 78 91 | 
             
                    file.rewind
         | 
| 79 92 | 
             
                    child_env = eval(file.read)
         | 
| 80 93 |  | 
| @@ -89,7 +102,7 @@ describe ChildProcess do | |
| 89 102 |  | 
| 90 103 | 
             
                Tempfile.open("argv-spec") do |file|
         | 
| 91 104 | 
             
                  process = write_argv(file.path, *args).start
         | 
| 92 | 
            -
                  process. | 
| 105 | 
            +
                  process.wait
         | 
| 93 106 |  | 
| 94 107 | 
             
                  file.rewind
         | 
| 95 108 | 
             
                  file.read.should == args.inspect
         | 
| @@ -119,7 +132,7 @@ describe ChildProcess do | |
| 119 132 |  | 
| 120 133 | 
             
                  process.start
         | 
| 121 134 | 
             
                  process.io.stdin.should be_nil
         | 
| 122 | 
            -
                  process. | 
| 135 | 
            +
                  process.wait
         | 
| 123 136 |  | 
| 124 137 | 
             
                  out.rewind
         | 
| 125 138 | 
             
                  err.rewind
         | 
| @@ -133,11 +146,10 @@ describe ChildProcess do | |
| 133 146 | 
             
              end
         | 
| 134 147 |  | 
| 135 148 | 
             
              it "can write to stdin if duplex = true" do
         | 
| 136 | 
            -
                process =  | 
| 137 | 
            -
                  puts(STDIN.gets.chomp)
         | 
| 138 | 
            -
                CODE
         | 
| 149 | 
            +
                process = cat
         | 
| 139 150 |  | 
| 140 151 | 
             
                out = Tempfile.new("duplex")
         | 
| 152 | 
            +
                out.sync = true
         | 
| 141 153 |  | 
| 142 154 | 
             
                begin
         | 
| 143 155 | 
             
                  process.io.stdout = out
         | 
| @@ -146,7 +158,7 @@ describe ChildProcess do | |
| 146 158 |  | 
| 147 159 | 
             
                  process.start
         | 
| 148 160 | 
             
                  process.io.stdin.puts "hello world"
         | 
| 149 | 
            -
                  process.io.stdin.close | 
| 161 | 
            +
                  process.io.stdin.close
         | 
| 150 162 |  | 
| 151 163 | 
             
                  process.poll_for_exit(EXIT_TIMEOUT)
         | 
| 152 164 |  | 
| @@ -177,7 +189,7 @@ describe ChildProcess do | |
| 177 189 | 
             
                  process.io.stdout = process.io.stderr = file
         | 
| 178 190 |  | 
| 179 191 | 
             
                  process.start
         | 
| 180 | 
            -
                  process. | 
| 192 | 
            +
                  process.wait
         | 
| 181 193 |  | 
| 182 194 | 
             
                  file.rewind
         | 
| 183 195 | 
             
                  file.read.should == Dir.pwd
         | 
| @@ -189,11 +201,16 @@ describe ChildProcess do | |
| 189 201 |  | 
| 190 202 | 
             
                Tempfile.open("argv-spec") do |file|
         | 
| 191 203 | 
             
                  process = write_argv(file.path, *args).start
         | 
| 192 | 
            -
                  process. | 
| 204 | 
            +
                  process.wait
         | 
| 193 205 |  | 
| 194 206 | 
             
                  file.rewind
         | 
| 195 207 | 
             
                  file.read.should == args.inspect
         | 
| 196 208 | 
             
                end
         | 
| 197 209 | 
             
              end
         | 
| 198 210 |  | 
| 211 | 
            +
              it "times out when polling for exit" do
         | 
| 212 | 
            +
                process = sleeping_ruby.start
         | 
| 213 | 
            +
                lambda { process.poll_for_exit(0.1) }.should raise_error(ChildProcess::TimeoutError)
         | 
| 214 | 
            +
              end
         | 
| 215 | 
            +
             | 
| 199 216 | 
             
            end
         | 
    
        data/spec/pid_behavior.rb
    CHANGED
    
    | @@ -4,7 +4,7 @@ shared_examples_for "a platform that provides the child's pid" do | |
| 4 4 | 
             
              it "knows the child's pid" do
         | 
| 5 5 | 
             
                Tempfile.open("pid-spec") do |file|
         | 
| 6 6 | 
             
                  process = write_pid(file.path).start
         | 
| 7 | 
            -
                  process. | 
| 7 | 
            +
                  process.wait
         | 
| 8 8 | 
             
                  file.rewind
         | 
| 9 9 |  | 
| 10 10 | 
             
                  process.pid.should == file.read.chomp.to_i
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -18,6 +18,10 @@ module ChildProcessSpecHelper | |
| 18 18 | 
             
                ruby_process("-e", "sleep")
         | 
| 19 19 | 
             
              end
         | 
| 20 20 |  | 
| 21 | 
            +
              def invalid_process
         | 
| 22 | 
            +
                @process = ChildProcess.build("unlikely-to-exist")
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 21 25 | 
             
              def ignored(signal)
         | 
| 22 26 | 
             
                code = <<-RUBY
         | 
| 23 27 | 
             
                  trap(#{signal.inspect}, "IGNORE")
         | 
| @@ -90,6 +94,19 @@ module ChildProcessSpecHelper | |
| 90 94 | 
             
                raise last_error unless ok
         | 
| 91 95 | 
             
              end
         | 
| 92 96 |  | 
| 97 | 
            +
              def cat
         | 
| 98 | 
            +
                if ChildProcess.os == :windows
         | 
| 99 | 
            +
                  ruby(<<-CODE)
         | 
| 100 | 
            +
                        STDIN.sync  = true
         | 
| 101 | 
            +
                        STDOUT.sync = true
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                        puts STDIN.read
         | 
| 104 | 
            +
                      CODE
         | 
| 105 | 
            +
                else
         | 
| 106 | 
            +
                  ChildProcess.build("cat")
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
              end
         | 
| 109 | 
            +
             | 
| 93 110 | 
             
              def ruby(code)
         | 
| 94 111 | 
             
                ruby_process(tmp_script(code))
         | 
| 95 112 | 
             
              end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: childprocess
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              hash:  | 
| 4 | 
            +
              hash: 31
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 0
         | 
| 8 8 | 
             
              - 2
         | 
| 9 | 
            -
              -  | 
| 10 | 
            -
              version: 0.2. | 
| 9 | 
            +
              - 4
         | 
| 10 | 
            +
              version: 0.2.4
         | 
| 11 11 | 
             
            platform: ruby
         | 
| 12 12 | 
             
            authors: 
         | 
| 13 13 | 
             
            - Jari Bakken
         | 
| @@ -15,7 +15,7 @@ autorequire: | |
| 15 15 | 
             
            bindir: bin
         | 
| 16 16 | 
             
            cert_chain: []
         | 
| 17 17 |  | 
| 18 | 
            -
            date: 2011- | 
| 18 | 
            +
            date: 2011-12-27 00:00:00 Z
         | 
| 19 19 | 
             
            dependencies: 
         | 
| 20 20 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 21 21 | 
             
              name: rspec
         | 
| @@ -105,7 +105,7 @@ files: | |
| 105 105 | 
             
            - lib/childprocess/jruby.rb
         | 
| 106 106 | 
             
            - lib/childprocess/jruby/io.rb
         | 
| 107 107 | 
             
            - lib/childprocess/jruby/process.rb
         | 
| 108 | 
            -
            - lib/childprocess/jruby/ | 
| 108 | 
            +
            - lib/childprocess/jruby/pump.rb
         | 
| 109 109 | 
             
            - lib/childprocess/unix.rb
         | 
| 110 110 | 
             
            - lib/childprocess/unix/io.rb
         | 
| 111 111 | 
             
            - lib/childprocess/unix/process.rb
         | 
| @@ -1,29 +0,0 @@ | |
| 1 | 
            -
            module ChildProcess
         | 
| 2 | 
            -
              module JRuby
         | 
| 3 | 
            -
                class Redirector
         | 
| 4 | 
            -
                  BUFFER_SIZE = 2048
         | 
| 5 | 
            -
             | 
| 6 | 
            -
                  def initialize(input, output)
         | 
| 7 | 
            -
                    @input = input
         | 
| 8 | 
            -
                    @output = output
         | 
| 9 | 
            -
                    @buffer = Java.byte[BUFFER_SIZE].new
         | 
| 10 | 
            -
                  end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                  def run
         | 
| 13 | 
            -
                    read, avail = 0, 0
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                    while(read != -1)
         | 
| 16 | 
            -
                      avail = [@input.available, 1].max
         | 
| 17 | 
            -
                      read  = @input.read(@buffer, 0, avail)
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                      if read > 0
         | 
| 20 | 
            -
                        @output.write(@buffer, 0, read)
         | 
| 21 | 
            -
                      end
         | 
| 22 | 
            -
                    end
         | 
| 23 | 
            -
                  rescue java.io.IOException => ex
         | 
| 24 | 
            -
                    $stderr.puts ex.message, ex.backtrace if $DEBUG
         | 
| 25 | 
            -
                  end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                end # Redirector
         | 
| 28 | 
            -
              end # JRuby
         | 
| 29 | 
            -
            end # ChildProcess
         |