Skip to content

Commit

Permalink
Add support for streaming stdout/stderr from Child invocations
Browse files Browse the repository at this point in the history
  • Loading branch information
brianmario committed Dec 30, 2016
1 parent 5dbafc2 commit 9206712
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
27 changes: 25 additions & 2 deletions lib/posix/spawn/child.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ def initialize(*args)
@options[:pgroup] = true
end
@options.delete(:chdir) if @options[:chdir].nil?
@streaming = false
if streams = @options.delete(:streams)
@stdout_block = streams[:stdout]
@stderr_block = streams[:stderr]

@streaming = !!@stdout_block || !!@stderr_block
end
exec! if !@options.delete(:noexec)
end

Expand Down Expand Up @@ -244,14 +251,30 @@ def read_and_write(input, stdin, stdout, stderr, timeout=nil, max=nil)

# read from stdout and stderr streams
ready[0].each do |fd|
buf = (fd == stdout) ? @out : @err
chunk = nil
begin
buf << fd.readpartial(BUFSIZE)
chunk = fd.readpartial(BUFSIZE)
rescue Errno::EAGAIN, Errno::EINTR
rescue EOFError
readers.delete(fd)
fd.close
end

if chunk
if fd == stdout
if @streaming && @stdout_block
@stdout_block.call(chunk)
else
@out << chunk
end
else
if @streaming && @stderr_block
@stderr_block.call(chunk)
else
@err << chunk
end
end
end
end

# keep tabs on the total amount of time we've spent here
Expand Down
30 changes: 30 additions & 0 deletions test/test_child.rb
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,36 @@ def test_utf8_input_long
assert p.success?
end

def test_streaming_stdout
stdout_buf = ""
stdout_stream = Proc.new do |chunk|
stdout_buf << chunk
end

input = "hello!"
p = Child.new('cat', :input => input, :streams => {
:stdout => stdout_stream
})

assert p.success?
assert_equal input, stdout_buf
end

def test_streaming_stderr
stderr_buf = ""
stderr_stream = Proc.new do |chunk|
stderr_buf << chunk
end

input = "hello!"
p = Child.new('ls', '-?', :input => input, :streams => {
:stderr => stderr_stream
})

refute p.success?
refute stderr_buf.empty?
end

##
# Assertion Helpers

Expand Down

0 comments on commit 9206712

Please sign in to comment.