Class: Arachni::Processes::Manager
- Includes:
- Singleton
- Defined in:
- lib/arachni/processes/manager.rb
Overview
Helper for managing processes.
Constant Summary collapse
- RUNNER =
"#{File.dirname( __FILE__ )}/executables/base.rb"
Instance Attribute Summary collapse
-
#pids ⇒ Array<Integer>
readonly
PIDs of all running processes.
Class Method Summary collapse
Instance Method Summary collapse
-
#<<(pid) ⇒ Integer
‘pid`.
- #discard_output ⇒ Object
- #discard_output? ⇒ Boolean
-
#initialize ⇒ Manager
constructor
A new instance of Manager.
- #kill(pid) ⇒ Object
- #kill_many(pids) ⇒ Object
-
#kill_reactor ⇒ Object
Stops the Reactor.
-
#killall ⇒ Object
Kills all processes.
-
#preserve_output ⇒ Object
Overrides the default setting of discarding process outputs.
- #preserve_output? ⇒ Boolean
-
#spawn(executable, options = {}) ⇒ Integer
PID of the process.
Constructor Details
#initialize ⇒ Manager
Returns a new instance of Manager.
26 27 28 29 |
# File 'lib/arachni/processes/manager.rb', line 26 def initialize @pids = [] @discard_output = true end |
Instance Attribute Details
#pids ⇒ Array<Integer> (readonly)
Returns PIDs of all running processes.
24 25 26 |
# File 'lib/arachni/processes/manager.rb', line 24 def pids @pids end |
Class Method Details
.method_missing(sym, *args, &block) ⇒ Object
156 157 158 159 160 161 162 |
# File 'lib/arachni/processes/manager.rb', line 156 def self.method_missing( sym, *args, &block ) if instance.respond_to?( sym ) instance.send( sym, *args, &block ) else super( sym, *args, &block ) end end |
.respond_to?(m) ⇒ Boolean
164 165 166 |
# File 'lib/arachni/processes/manager.rb', line 164 def self.respond_to?( m ) super( m ) || instance.respond_to?( m ) end |
Instance Method Details
#<<(pid) ⇒ Integer
Returns ‘pid`.
35 36 37 38 39 |
# File 'lib/arachni/processes/manager.rb', line 35 def <<( pid ) @pids << pid Process.detach pid pid end |
#discard_output ⇒ Object
87 88 89 |
# File 'lib/arachni/processes/manager.rb', line 87 def discard_output @discard_output = true end |
#discard_output? ⇒ Boolean
91 92 93 |
# File 'lib/arachni/processes/manager.rb', line 91 def discard_output? @discard_output end |
#kill(pid) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/arachni/processes/manager.rb', line 42 def kill( pid ) Timeout.timeout 10 do while sleep 0.1 do begin # I'd rather this be an INT but WEBrick's INT traps write to # the Logger and multiple INT signals force it to write to a # closed logger and crash. Process.kill( Gem.win_platform? ? 'QUIT' : 'KILL', pid ) rescue Errno::ESRCH @pids.delete pid return end end end rescue Timeout::Error end |
#kill_many(pids) ⇒ Object
61 62 63 |
# File 'lib/arachni/processes/manager.rb', line 61 def kill_many( pids ) pids.each { |pid| kill pid } end |
#kill_reactor ⇒ Object
Stops the Reactor.
72 73 74 75 76 |
# File 'lib/arachni/processes/manager.rb', line 72 def kill_reactor Reactor.stop rescue nil end |
#killall ⇒ Object
Kills all processes.
66 67 68 69 |
# File 'lib/arachni/processes/manager.rb', line 66 def killall kill_many @pids.dup @pids.clear end |
#preserve_output ⇒ Object
Overrides the default setting of discarding process outputs.
79 80 81 |
# File 'lib/arachni/processes/manager.rb', line 79 def preserve_output @discard_output = false end |
#preserve_output? ⇒ Boolean
83 84 85 |
# File 'lib/arachni/processes/manager.rb', line 83 def preserve_output? !discard_output? end |
#spawn(executable, options = {}) ⇒ Integer
Returns PID of the process.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/arachni/processes/manager.rb', line 103 def spawn( executable, = {} ) fork = .delete(:fork) fork = true if fork.nil? [:options] ||= {} [:options] = Options.to_h.merge( [:options] ) # Paths are not included in RPC nor Hash representations as they're # considered local, in this case though they're necessary to provide # the same environment the processes. [:options][:paths] = Options.paths.to_h executable = "#{Options.paths.executables}/#{executable}.rb" = Base64.strict_encode64( Marshal.dump( ) ) argv = [executable, ] # Process.fork is faster, less stressful to the CPU and lets the parent # and child share the same RAM due to copy-on-write support on Ruby 2.0.0. # It is, however, not available when running on Windows nor JRuby so # have a fallback ready. if fork && Process.respond_to?( :fork ) pid = Process.fork do if discard_output? $stdout.reopen( Arachni.null_device, 'w' ) $stderr.reopen( Arachni.null_device, 'w' ) end # Careful, Framework.reset will remove objects from Data # structures which off-load to disk, those files however belong # to our parent and should not be touched, thus, we remove # any references to them. Data.framework.page_queue.disk.clear Data.framework.url_queue.disk.clear Data.framework.rpc.distributed_page_queue.disk.clear # Provide a clean slate. Framework.reset Reactor.stop ARGV.replace( argv ) load RUNNER end else # It's very, **VERY** important that we use this argument format as # it bypasses the OS shell and we can thus count on a 1-to-1 process # creation and that the PID we get will be for the actual process. pid = Process.spawn( RbConfig.ruby, RUNNER, *argv ) end self << pid pid end |