-
-
Save gruis/1333428 to your computer and use it in GitHub Desktop.
Capture stderr data on EventMachine.popen
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby -wW1 | |
require 'eventmachine' | |
module EventMachine | |
# @see http://eventmachine.rubyforge.org/EventMachine.html#M000491 | |
def self.popen3(cmd, handler=nil, *args) | |
klass = klass_from_handler(Connection, handler, *args) | |
w = Shellwords::shellwords(cmd) | |
w.unshift(w.first) if w.first | |
new_stderr = $stderr.dup | |
rd, wr = IO::pipe | |
$stderr.reopen wr | |
s = invoke_popen(w) | |
$stderr.reopen new_stderr | |
klass.new(s, *args).tap do |c| | |
EM.attach(rd, Popen3StderrHandler, c) | |
@conns[s] = c | |
yield(c) if block_given? | |
end | |
end | |
class Popen3StderrHandler < EventMachine::Connection | |
def initialize(connection) | |
@connection = connection | |
end | |
def receive_data(data) | |
@connection.receive_stderr(data) | |
end | |
end # class::Popen3StderrHandler | |
end # module::EventMachine | |
class CountRecvr < EventMachine::Connection | |
include EventMachine::Deferrable | |
class << self | |
def start(cmd, *args) | |
EM.popen3(cmd, self, *args).tap { |o| yield(o) if block_given? } | |
end | |
end # << self | |
def initialize(cnt = 5) | |
$stderr.puts("#{self.class}.new(#{cnt}) -> #{self}") | |
@cnt = cnt | |
@data = "" | |
end | |
def post_init | |
$stderr.puts "post init from parent" | |
send_data("#{@cnt}\n") | |
end | |
def receive_data(d) | |
puts "receive data from child: #{d.dump}" | |
@data << d | |
@data.include?("#{self}") && raise("stderr is shared by parent and child!") | |
end | |
alias :receive_stderr :receive_data | |
def unbind | |
get_status.exitstatus == 0 ? succeed(@data, self) : fail(@data, self) | |
end | |
end # class::CountRecvr < EventMachine::Connection | |
# @see http://eventmachine.rubyforge.org/EventMachine.html#M000491 | |
# @see https://gist.github.com/535644 | |
EM.run { | |
CountRecvr.start(%q{ruby -e' gets.to_i.times{ |i| $stderr.puts i+1; sleep 1 }'}, ARGV[0] || 3) do |cntr| | |
cntr.callback { EM.stop } | |
cntr.errback { EM.stop } | |
end | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment