A
ara howard
this works on *nix and might on windoze - i don't have a box near so
cannot test... can someone give it a whirl and/or patch it to work?
it should simply run forever:
require 'socket'
STDIN.sync = STDOUT.sync = STDERR.sync = true
class IO
windoze = RUBY_PLATFORM.include?('win32')
unless windoze
def IO.socketpair(sync=true)
one, two = UNIXSocket.socketpair
one.sync = two.sync = true if sync
[one, two]
end
def IO.spawn cmd, options = {}
stdin = IO.socketpair
stdout = IO.socketpair
stderr = IO.socketpair
if cid = fork
stdin.last.close
stdout.last.close
stderr.last.close
else
STDIN.reopen stdin.last
STDOUT.reopen stdout.last
STDERR.reopen stderr.last
exec cmd
end
at_exit do
Process.kill(15, cid) rescue nil
Process.kill(-9, cid) rescue nil
end
[ cid, stdin.first, stdout.first, stderr.first ]
end
else
def IO.socketpair(sync=true)
tcp = TCPServer.new('127.0.0.1', 0)
one = TCPSocket.new('127.0.0.1', tcp.addr[1])
two = tcp.accept and tcp.close
one.sync = two.sync = true if sync
[one, two]
end
def IO.spawn cmd, options = {}
stdin = IO.socketpair
stdout = IO.socketpair
stderr = IO.socketpair
require 'win32/process'
child = Process.create(
'app_name' => "cmd /k #{cmd}", # the "/k" keeps the process
around when it's done
'process_inherit' => true, # not yet sure if this one is
actually needed
'thread_inherit' => true, # not yet sure if this one is
actually needed
'startup_info' => {
'stdin' => stdin.last,
'stdout' => stdout.last,
'stderr' => stderr.last,
}
)
at_exit do
Process.TerminateProcess(child.process_handle,
child.process_id) rescue nil
Process.CloseHandle(child.process_handle) rescue nil
Process.kill(-9, child.process_id) rescue nil
end
stdin.last.close
stdout.last.close
stderr.last.close
[ child.process_id, stdin.first, stdout.first, stderr.first ]
end
end
end
#
# try to clog the pipes
#
cid, i, o, e = IO.spawn ' ruby -e"
loop{ STDOUT.puts(Time.now.to_f); STDERR.puts(Time.now.to_f) }" '
a = Thread.new do
loop{ STDOUT.puts o.gets }
end
b = Thread.new do
loop{ STDOUT.puts e.gets }
end
sleep
a @ http://codeforpeople.com/
cannot test... can someone give it a whirl and/or patch it to work?
it should simply run forever:
require 'socket'
STDIN.sync = STDOUT.sync = STDERR.sync = true
class IO
windoze = RUBY_PLATFORM.include?('win32')
unless windoze
def IO.socketpair(sync=true)
one, two = UNIXSocket.socketpair
one.sync = two.sync = true if sync
[one, two]
end
def IO.spawn cmd, options = {}
stdin = IO.socketpair
stdout = IO.socketpair
stderr = IO.socketpair
if cid = fork
stdin.last.close
stdout.last.close
stderr.last.close
else
STDIN.reopen stdin.last
STDOUT.reopen stdout.last
STDERR.reopen stderr.last
exec cmd
end
at_exit do
Process.kill(15, cid) rescue nil
Process.kill(-9, cid) rescue nil
end
[ cid, stdin.first, stdout.first, stderr.first ]
end
else
def IO.socketpair(sync=true)
tcp = TCPServer.new('127.0.0.1', 0)
one = TCPSocket.new('127.0.0.1', tcp.addr[1])
two = tcp.accept and tcp.close
one.sync = two.sync = true if sync
[one, two]
end
def IO.spawn cmd, options = {}
stdin = IO.socketpair
stdout = IO.socketpair
stderr = IO.socketpair
require 'win32/process'
child = Process.create(
'app_name' => "cmd /k #{cmd}", # the "/k" keeps the process
around when it's done
'process_inherit' => true, # not yet sure if this one is
actually needed
'thread_inherit' => true, # not yet sure if this one is
actually needed
'startup_info' => {
'stdin' => stdin.last,
'stdout' => stdout.last,
'stderr' => stderr.last,
}
)
at_exit do
Process.TerminateProcess(child.process_handle,
child.process_id) rescue nil
Process.CloseHandle(child.process_handle) rescue nil
Process.kill(-9, child.process_id) rescue nil
end
stdin.last.close
stdout.last.close
stderr.last.close
[ child.process_id, stdin.first, stdout.first, stderr.first ]
end
end
end
#
# try to clog the pipes
#
cid, i, o, e = IO.spawn ' ruby -e"
loop{ STDOUT.puts(Time.now.to_f); STDERR.puts(Time.now.to_f) }" '
a = Thread.new do
loop{ STDOUT.puts o.gets }
end
b = Thread.new do
loop{ STDOUT.puts e.gets }
end
sleep
a @ http://codeforpeople.com/