Skip to content

Instantly share code, notes, and snippets.

@careo
Created March 17, 2009 05:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save careo/80296 to your computer and use it in GitHub Desktop.
Save careo/80296 to your computer and use it in GitHub Desktop.
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 '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
class Process < EventMachine::Connection
def initialize *args
log __method__, args
end
def receive_data data
log __method__, data
end
def unbind
log __method__
end
end
end
class MyStderr < EventMachine::Connection
def initialize stderr
@stderr = stderr
end
# Note: using receive_data here instead mysteriously breaks
# this on linux....
def notify_readable
log __method__, @stderr.read
end
end
def popen3 cmd, stdio_handler, stderr_handler
new_stderr = $stderr.dup
rd, wr = IO::pipe
$stderr.reopen wr
EM.popen cmd, stdio_handler
EM.attach rd, stderr_handler, rd
$stderr.reopen new_stderr
end
BEGIN { require 'rubygems' if __FILE__ == $0 }
if __FILE__ == $0
file = "#{File.dirname(__FILE__)}/external-cmd.rb"
cmd = "ruby #{file}"
EM.run {
EM.next_tick {
$stderr.puts "stderr before"
popen3 cmd, EM::Process, MyStderr
$stderr.puts "stderr after"
}
EM.add_timer(2) {
log :exit
EM.stop
}
}
end
@tokland
Copy link

tokland commented Aug 18, 2010

Note: using receive_data here instead mysteriously breaks

this on linux....

That's weird, using receive_data handler in MyStderr worked for me. Maybe you were getting some error and the stderr redirection shadowed it? With minor modification we end with a pretty comfy API:

http://gist.github.com/535644

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment