Skip to content

Instantly share code, notes, and snippets.

@vitobotta
Forked from tokland/external-command.rb
Created October 4, 2012 18:12
Show Gist options
  • Save vitobotta/3835362 to your computer and use it in GitHub Desktop.
Save vitobotta/3835362 to your computer and use it in GitHub Desktop.
Capture stderr data on EventMachine.popen
require 'rubygems'
require 'eventmachine'
$stdout.sync = true
$stderr.sync = true
EM.run {
EM.add_periodic_timer(0.1) {
$stdout.write "stdout\n"
}
EM.add_periodic_timer(0.1) {
$stderr.write "stderr\n"
}
EM.add_timer(1) {
$stdout.write "stopping from stdout...\n"
$stderr.write "stopping from stderr...\n"
EM.stop
}
}
require 'rubygems'
require 'eventmachine'
if RUBY_VERSION < "1.8.7"
def __method__
caller = /`(.*)'/
Kernel.caller.first.split(caller).last.to_sym
end
end
def log *message
p [Time.now, *message]
end
module EventMachine
def self.popen3(*args)
new_stderr = $stderr.dup
rd, wr = IO::pipe
$stderr.reopen wr
connection = EM.popen(*args)
$stderr.reopen new_stderr
EM.attach rd, Popen3StderrHandler, connection
connection
end
class Popen3StderrHandler < EventMachine::Connection
def initialize(connection)
@connection = connection
end
def receive_data(data)
@connection.receive_stderr(data)
end
end
end
class MyProcess < EventMachine::Connection
def initialize *args
log __method__, args
end
def receive_data data
log __method__, data
end
def receive_stderr data
log __method__, data
end
def unbind
log __method__
end
end
if __FILE__ == $0
cmd = "ruby #{File.dirname(__FILE__)}/external-command.rb"
EM.run do
EM.next_tick do
$stderr.puts "stderr before"
EM.popen3 cmd, MyProcess
$stderr.puts "stderr after"
end
EM.add_timer(2) do
log :exit
EM.stop
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment