3 # Author:: Francis Cianfrocca (gmail: blackhedd)
4 # Homepage:: http://rubyeventmachine.com
7 # See EventMachine and EventMachine::Connection for documentation and
10 #----------------------------------------------------------------------------
12 # Copyright (C) 2006-08 by Francis Cianfrocca. All Rights Reserved.
15 # This program is free software; you can redistribute it and/or modify
16 # it under the terms of either: 1) the GNU General Public License
17 # as published by the Free Software Foundation; either version 2 of the
18 # License, or (at your option) any later version; or 2) Ruby's License.
20 # See the file COPYING for complete licensing information.
22 #---------------------------------------------------------------------------
29 # EM::DeferrableChildProcess is a sugaring of a common use-case
30 # involving EM::popen.
31 # Call the #open method on EM::DeferrableChildProcess, passing
32 # a command-string. #open immediately returns an EM::Deferrable
33 # object. It also schedules the forking of a child process, which
34 # will execute the command passed to #open.
35 # When the forked child terminates, the Deferrable will be signalled
36 # and execute its callbacks, passing the data that the child process
39 class DeferrableChildProcess < EventMachine::Connection
40 include EventMachine::Deferrable
42 def initialize # :nodoc:
47 # Sugars a common use-case involving forked child processes.
48 # #open takes a String argument containing an shell command
49 # string (including arguments if desired). #open immediately
50 # returns an EventMachine::Deferrable object, without blocking.
52 # It also invokes EventMachine#popen to run the passed-in
53 # command in a forked child process.
55 # When the forked child terminates, the Deferrable that
56 # #open calls its callbacks, passing the data returned
57 # from the child process.
60 EventMachine.popen( cmd, DeferrableChildProcess )
63 def receive_data data # :nodoc:
72 class SystemCmd < EventMachine::Connection # :nodoc:
81 @cb.call @output.join(''), get_status if @cb
85 # EM::system is a simple wrapper for EM::popen. It is similar to Kernel::system, but requires a
86 # single string argument for the command and performs no shell expansion.
88 # The block or proc passed to EM::system is called with two arguments: the output generated by the command,
89 # and a Process::Status that contains information about the command's execution.
92 # EM.system('ls'){ |output,status| puts output if status.exitstatus == 0 }
95 # You can also supply an additional proc to send some data to the process:
98 # EM.system('sh', proc{ |process|
99 # process.send_data("echo hello\n")
100 # process.send_data("exit\n")
101 # }, proc{ |out,status|
106 # Like EventMachine.popen, EventMachine.system currently does not work on windows.
107 # It returns the pid of the spawned process.
108 def EventMachine::system cmd, *args, &cb
109 cb ||= args.pop if args.last.is_a? Proc
110 init = args.pop if args.last.is_a? Proc
112 # merge remaining arguments into the command
113 cmd = ([cmd] + args.map{|a|a.to_s.dump}).join(' ')
115 EM.get_subprocess_pid(EM.popen(cmd, SystemCmd, cb) do |c|