hijack 0.2.0.rc2 → 0.2.0.rc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/hijack.rb +2 -2
- data/lib/hijack/gdb.rb +2 -2
- data/lib/hijack/output_receiver.rb +41 -21
- data/lib/hijack/payload.rb +62 -73
- data/lib/hijack/workspace.rb +2 -1
- data/test/test.rb +1 -1
- metadata +4 -4
data/lib/hijack.rb
CHANGED
data/lib/hijack/gdb.rb
CHANGED
@@ -49,7 +49,7 @@ module Hijack
|
|
49
49
|
unless attached
|
50
50
|
puts
|
51
51
|
puts "=> Tried 3 times to attach to #{@pid} whilst GC wasn't running but failed."
|
52
|
-
puts "=> This means either the process calls GC.start frequently or
|
52
|
+
puts "=> This means either the process calls GC.start frequently or GC runs are slow - try hijacking again."
|
53
53
|
exit 1
|
54
54
|
end
|
55
55
|
|
@@ -58,7 +58,7 @@ module Hijack
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def during_gc?
|
61
|
-
|
61
|
+
!!(call("(int)rb_during_gc()").first =~ /\$[\d]+ = 1/)
|
62
62
|
end
|
63
63
|
|
64
64
|
def detach
|
@@ -1,22 +1,38 @@
|
|
1
1
|
module Hijack
|
2
2
|
class OutputReceiver
|
3
|
-
|
3
|
+
def self.pid
|
4
|
+
@pid
|
5
|
+
end
|
4
6
|
|
5
7
|
def self.start(remote)
|
8
|
+
@started = true
|
6
9
|
@instance = new(remote)
|
7
|
-
@
|
10
|
+
@pid = fork do
|
11
|
+
@instance.start
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.started?
|
16
|
+
@started
|
8
17
|
end
|
9
18
|
|
10
19
|
def self.stop
|
11
|
-
|
20
|
+
if started?
|
21
|
+
Process.kill("KILL", @pid)
|
22
|
+
Process.waitpid(@pid)
|
23
|
+
end
|
12
24
|
end
|
13
25
|
|
14
26
|
def self.mute
|
15
|
-
|
27
|
+
Process.kill(Signal.list["USR1"], @pid) if started?
|
16
28
|
end
|
17
29
|
|
18
30
|
def self.unmute
|
19
|
-
|
31
|
+
Process.kill(Signal.list["USR2"], @pid) if started?
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.mute_momentarily
|
35
|
+
Process.kill(Signal.list["HUP"], @pid) if started?
|
20
36
|
end
|
21
37
|
|
22
38
|
def initialize(remote)
|
@@ -24,30 +40,34 @@ module Hijack
|
|
24
40
|
end
|
25
41
|
|
26
42
|
def start
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
DRb.thread.join
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def stop
|
36
|
-
Process.kill("KILL", @pid)
|
37
|
-
Process.waitpid(@pid)
|
43
|
+
setup_signal_traps
|
44
|
+
DRb.start_service(Hijack.socket_for(Process.pid), self)
|
45
|
+
@remote.evaluate("OutputCopier.start(#{Process.pid})")
|
46
|
+
DRb.thread.join
|
38
47
|
end
|
39
|
-
|
48
|
+
|
40
49
|
def setup_signal_traps
|
41
|
-
Signal.trap("USR1") {
|
42
|
-
Signal.trap("USR2") {
|
50
|
+
Signal.trap("USR1") { mute }
|
51
|
+
Signal.trap("USR2") { unmute }
|
52
|
+
Signal.trap("HUP") { mute_momentarily }
|
43
53
|
end
|
44
54
|
|
45
55
|
def mute
|
46
|
-
|
56
|
+
@mute = true
|
57
|
+
@explicit_mute = true
|
47
58
|
end
|
48
59
|
|
49
60
|
def unmute
|
50
|
-
|
61
|
+
@mute = false
|
62
|
+
@explicit_mute = false
|
63
|
+
end
|
64
|
+
|
65
|
+
def mute_momentarily
|
66
|
+
@mute = true
|
67
|
+
Thread.new do
|
68
|
+
sleep 3
|
69
|
+
@mute = false unless @explicit_mute
|
70
|
+
end
|
51
71
|
end
|
52
72
|
|
53
73
|
def write(io, str)
|
data/lib/hijack/payload.rb
CHANGED
@@ -18,98 +18,87 @@ module Hijack
|
|
18
18
|
require 'drb'
|
19
19
|
|
20
20
|
debug = #{Hijack.options[:debug] || false}
|
21
|
-
if debug
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
21
|
+
puts 'Hijack: Debugging enabled' if debug
|
22
|
+
module Hijack
|
23
|
+
class OutputCopier
|
24
|
+
def self.remote
|
25
|
+
@remote
|
26
|
+
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
28
|
+
def self.stop
|
29
|
+
@remote = nil
|
30
|
+
[$stdout, $stderr].each do |io|
|
31
|
+
if io.respond_to?(:write_with_copying)
|
32
|
+
class << io
|
33
|
+
alias_method :write, :write_without_copying
|
34
|
+
remove_method :write_with_copying
|
37
35
|
end
|
38
36
|
end
|
39
37
|
end
|
38
|
+
end
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
def self.start(pid)
|
41
|
+
@remote = DRbObject.new(nil, 'drbunix://tmp/hijack.' + pid.to_s + '.sock')
|
42
|
+
puts @remote.inspect if Hijack.debug?
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
44
|
+
class << $stdout
|
45
|
+
def write_with_copying(str)
|
46
|
+
write_without_copying(str)
|
47
|
+
begin
|
48
|
+
Hijack::OutputCopier.remote.write('stdout', str)
|
49
|
+
rescue Exception => e
|
50
|
+
write_without_copying(e.message) if Hijack.debug?
|
51
|
+
Hijack.stop
|
54
52
|
end
|
55
|
-
alias_method :write_without_copying, :write
|
56
|
-
alias_method :write, :write_with_copying
|
57
53
|
end
|
54
|
+
alias_method :write_without_copying, :write
|
55
|
+
alias_method :write, :write_with_copying
|
56
|
+
end
|
58
57
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
58
|
+
class << $stderr
|
59
|
+
def write_with_copying(str)
|
60
|
+
write_without_copying(str)
|
61
|
+
begin
|
62
|
+
Hijack::OutputCopier.remote.write('stderr', str)
|
63
|
+
rescue Exception => e
|
64
|
+
write_without_copying(e.message) if Hijack.debug?
|
65
|
+
Hijack.stop
|
68
66
|
end
|
69
|
-
alias_method :write_without_copying, :write
|
70
|
-
alias_method :write, :write_with_copying
|
71
67
|
end
|
68
|
+
alias_method :write_without_copying, :write
|
69
|
+
alias_method :write, :write_with_copying
|
72
70
|
end
|
73
71
|
end
|
72
|
+
end
|
74
73
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
@file = __FILE__
|
79
|
-
end
|
80
|
-
|
81
|
-
def evaluate(rb)
|
82
|
-
if rb =~ /__hijack_output_receiver_ready_([\\d]+)/
|
83
|
-
OutputCopier.start($1)
|
84
|
-
elsif rb =~ /__hijack_get_remote_file_name/
|
85
|
-
@file
|
86
|
-
elsif rb =~ /__hijack_exit/
|
87
|
-
Hijack.stop
|
88
|
-
else
|
89
|
-
@context.instance_eval(rb)
|
90
|
-
end
|
91
|
-
end
|
74
|
+
class Evaluator
|
75
|
+
def initialize(context)
|
76
|
+
@context = context
|
92
77
|
end
|
93
78
|
|
94
|
-
def
|
95
|
-
@
|
79
|
+
def evaluate(rb)
|
80
|
+
@context.instance_eval(rb)
|
96
81
|
end
|
82
|
+
end
|
97
83
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
evaluator = Hijack::Evaluator.new(context)
|
102
|
-
@service = DRb.start_service('#{Hijack.socket_for(pid)}', evaluator)
|
103
|
-
File.chmod(0600, '#{Hijack.socket_path_for(pid)}')
|
104
|
-
end
|
84
|
+
def self.debug?
|
85
|
+
@debug
|
86
|
+
end
|
105
87
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
88
|
+
def self.start(context, debug)
|
89
|
+
return if @service && @service.alive?
|
90
|
+
@debug = debug
|
91
|
+
evaluator = Hijack::Evaluator.new(context)
|
92
|
+
@service = DRb.start_service('#{Hijack.socket_for(pid)}', evaluator)
|
93
|
+
File.chmod(0600, '#{Hijack.socket_path_for(pid)}')
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.stop
|
97
|
+
begin
|
98
|
+
OutputCopier.stop
|
99
|
+
@service.stop_service
|
100
|
+
@service = nil
|
101
|
+
rescue Exception
|
113
102
|
end
|
114
103
|
end
|
115
104
|
end
|
data/lib/hijack/workspace.rb
CHANGED
@@ -2,6 +2,7 @@ module Hijack
|
|
2
2
|
Readline.completion_proc = Proc.new do |input|
|
3
3
|
bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
|
4
4
|
if helpers = Helper.helpers_like(input)
|
5
|
+
OutputReceiver.mute_momentarily
|
5
6
|
helpers
|
6
7
|
else
|
7
8
|
IRB::InputCompletor::CompletionProc.call(input)
|
@@ -14,7 +15,7 @@ module Hijack
|
|
14
15
|
if statements =~ /IRB\./
|
15
16
|
super
|
16
17
|
elsif statements.strip =~ /^(exit|quit)/
|
17
|
-
remote.evaluate('
|
18
|
+
remote.evaluate('Hijack.stop') rescue nil
|
18
19
|
super
|
19
20
|
elsif helper = Hijack::Helper.find_helper(statements)
|
20
21
|
Hijack::Helper.send(helper, remote)
|
data/test/test.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hijack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 977940572
|
5
5
|
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
9
|
- 0
|
10
|
-
-
|
11
|
-
version: 0.2.0.
|
10
|
+
- rc3
|
11
|
+
version: 0.2.0.rc3
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- Ian Leitch
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date:
|
19
|
+
date: 2011-02-15 00:00:00 +11:00
|
20
20
|
default_executable:
|
21
21
|
dependencies: []
|
22
22
|
|