rogerdpack-live_console 0.2.2.3 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,90 @@
1
+ require 'rake/gempackagetask'
2
+ require 'rake/rdoctask'
3
+ require 'lib/live_console_config'
4
+ require 'fileutils'
5
+
6
+ $: << "#{File.dirname(__FILE__)}/lib"
7
+
8
+ spec = Gem::Specification.new { |s|
9
+ s.name = LiveConsoleConfig::PkgName
10
+ s.version = LiveConsoleConfig::Version
11
+ s.author = LiveConsoleConfig::Authors
12
+ s.email = LiveConsoleConfig::Email
13
+ s.homepage = LiveConsoleConfig::URL
14
+ s.rubyforge_project = LiveConsoleConfig::Project
15
+
16
+ s.platform = Gem::Platform::RUBY
17
+
18
+ s.files = Dir["{lib,doc,bin,ext}/**/*"].delete_if {|f|
19
+ /\/rdoc(\/|$)/i.match f
20
+ } + %w(Rakefile)
21
+ s.require_path = 'lib'
22
+ s.has_rdoc = true
23
+ s.extra_rdoc_files = Dir['doc/*'].select(&File.method(:file?))
24
+ s.extensions << 'ext/extconf.rb' if File.exist? 'ext/extconf.rb'
25
+ Dir['bin/*'].map(&File.method(:basename)).map(&s.executables.method(:<<))
26
+
27
+ s.summary = 'A library to support adding an irb console to your ' \
28
+ 'running application.'
29
+ %w().each &s.method(:add_dependency)
30
+ }
31
+
32
+ Rake::RDocTask.new(:doc) { |t|
33
+ t.main = 'doc/README'
34
+ t.rdoc_files.include 'lib/**/*.rb', 'doc/*', 'bin/*', 'ext/**/*.c',
35
+ 'ext/**/*.rb'
36
+ t.options << '-S' << '-N'
37
+ t.rdoc_dir = 'doc/rdoc'
38
+ }
39
+
40
+ Rake::GemPackageTask.new(spec) { |pkg|
41
+ pkg.need_tar_bz2 = true
42
+ }
43
+
44
+ desc "Builds and installs the gem for #{spec.name}"
45
+ task(:install => :package) {
46
+ g = "pkg/#{spec.name}-#{spec.version}.gem"
47
+ system "sudo gem install -l #{g}"
48
+ }
49
+
50
+ desc "Runs IRB, automatically require()ing #{spec.name}."
51
+ task(:irb) {
52
+ exec "irb -Ilib -r#{spec.name}"
53
+ }
54
+
55
+ desc "Cleans up the pkg directory."
56
+ task(:clean) {
57
+ FileUtils.rm_rf 'pkg'
58
+ }
59
+
60
+ desc "Generates a static gemspec file; useful for github."
61
+ task(:static_gemspec) {
62
+ # This whole thing is hacky.
63
+ spec.validate
64
+ spec_attrs = %w(
65
+ platform author email files require_path has_rdoc extra_rdoc_files
66
+ extensions executables name summary homepage
67
+ ).map { |attr|
68
+ "\ts.#{attr} = #{spec.send(attr).inspect}\n"
69
+ }.join <<
70
+ "\ts.version = #{spec.version.to_s.inspect}\n" <<
71
+ spec.dependencies.map { |dep|
72
+ "\ts.add_dependency #{dep.inspect}\n"
73
+ }.join
74
+
75
+ File.open("#{spec.name}.gemspec", 'w') { |f|
76
+ f.print <<-EOGEMSPEC
77
+ # This is a static gempsec automatically generated by rake. It's better to
78
+ # edit the Rakefile than this file. It is kept in the repository for the
79
+ # benefit of github.
80
+
81
+ spec = Gem::Specification.new { |s|
82
+ #{spec_attrs}}
83
+ if __FILE__ == $0
84
+ Gem::Builder.new(spec).build
85
+ else
86
+ spec # Github wants this file to return the spec.
87
+ end
88
+ EOGEMSPEC
89
+ }
90
+ }
data/doc/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2007 Peter Elmore (pete.elmore at gmail.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a
4
+ copy of this software and associated documentation files (the "Software"),
5
+ to deal in the Software without restriction, including without limitation
6
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
+ and/or sell copies of the Software, and to permit persons to whom the
8
+ Software is furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19
+ DEALINGS IN THE SOFTWARE.
data/doc/README ADDED
@@ -0,0 +1,137 @@
1
+ = LiveConsole
2
+
3
+ == Summary
4
+
5
+ LiveConsole is a library for providing IRB over a TCP connection or a Unix
6
+ Domain Socket. If you add it to your application, you can run arbitrary code
7
+ against your application.
8
+ For example, you can:
9
+ * Inspect the state of a running application
10
+ * Change the state of the application
11
+ * Patch code on the fly, without a restart.
12
+ * Let anyone on the net 0wn you if you bind to a public interface. :)
13
+ It's useful as a diagnostic tool, a debugging tool, and a way to impress your
14
+ friends or get those Lisp guys off your back. You know the ones I mean.
15
+
16
+ == Stern Security Warning. Grrr.
17
+
18
+ Have a look at the bugs section. It should be pretty apparent that incorrect
19
+ use of this library could create a large security hole, especially before
20
+ authentication is implemented.
21
+
22
+ == Installation
23
+
24
+ You can install via rubygems,
25
+
26
+ gem install live_console
27
+
28
+ or plain old setup.rb:
29
+
30
+ ruby setup.rb install
31
+
32
+ == How to use LiveConsole
33
+
34
+ LiveConsole is very easy to use in your own app:
35
+
36
+ require 'rubygems'
37
+ require 'live_console'
38
+
39
+ # Create a LiveConsole using TCP on port 1337
40
+ lc = LiveConsole.new :socket, :port => 1337
41
+ # We're not yet accepting connections. We need to start it up:
42
+ lc.start # Starts the LiveConsole thread
43
+ # At this point, users can connect and get an IRB prompt.
44
+ lc.stop # Kills the LiveConsole thread
45
+ # Now, no one can connect.
46
+
47
+ # Create a LiveConsole using a Unix socket in /tmp/live-console.sock
48
+ lc = LiveConsole.new :unix_socket, :path => '/tmp/live-console.sock'
49
+ # As above:
50
+ lc.start
51
+ lc.stop
52
+
53
+ # Have a LiveConsole run code in a binding other than the top-level:
54
+ lc = LiveConsole.new :unix_socket, :path => '/tmp/live-console.sock'
55
+ :bind => binding
56
+ lc.start
57
+ # That will start IRB in the current binding. There is also an accessor:
58
+ lc.bind = binding
59
+ # Of course, you must restart before IRB will see the new binding:
60
+ lc.restart
61
+
62
+ Have a look at doc/lc_example.rb or doc/lc_unix_example.rb for brief examples
63
+ of how to use LiveConsole.
64
+
65
+ Try just running it:
66
+
67
+ $ ruby doc/lc_example.rb 4000 test
68
+ # Then, in a different shell:
69
+ $ netcat localhost 4000
70
+ irb(main):001:0> puts 'Wow, magic!'
71
+
72
+ $ ruby doc/lc_unix_example.rb /tmp/live-console.sock
73
+ # Then, in a different shell:
74
+ $ udscat /tmp/live-console.sock
75
+ irb(main):001:0> puts 'Words cannot describe the joy I feel.'
76
+
77
+ You can get creative about it, only starting LiveConsole when there's an
78
+ unhandled exception in your server, and then calling LiveConsole#stop when
79
+ you've diagnosed and fixed whatever the problem was.
80
+
81
+ Additionally, if you want to run LiveConsole on a server, but run netcat
82
+ locally, you can use SSH port forwarding to avoid having to open LiveConsole
83
+ to the world:
84
+
85
+ ssh -L4000:localhost:4000 you@server
86
+
87
+ Then, locally, you can do
88
+
89
+ netcat localhost 4000
90
+
91
+ and get the remote LiveConsole. man ssh for more details. Of course, this
92
+ only works for the TCP socket mode.
93
+
94
+ == Bugs
95
+
96
+ LiveConsole lacks many of the niceties of IRB on the console, like Readline
97
+ support. For this, you can actually use the wonderful rlwrap program, which
98
+ wraps an arbitrary interactive program in readline. For example, to connect to
99
+ a LiveConsole on localhost:3333, use
100
+ rlwrap netcat localhost 3333
101
+ rlwrap is available with most Linux distributions or at
102
+ http://utopia.knoware.nl/~hlub/uck/rlwrap/ . It is seriously an incredibly
103
+ useful piece of software.
104
+
105
+
106
+ Typing exit, hitting ^D, or sending signals (like INT or STOP) doesn't work.
107
+ Just exit the program you used to connect to it. This has more to do with the
108
+ program you use to connect to the socket.
109
+
110
+ For TCP connections, there is no authentication support yet, although it is
111
+ planned for the near future. This creates a security risk: anyone that can
112
+ connect to the socket can run arbitrary Ruby code as the user who owns the
113
+ process. In fact, even binding to localhost can be a security issue if you're
114
+ on a box with any untrusted users. If there's a chance you don't know what
115
+ you're doing, avoid using this library. The Unix Domain Socket version is more
116
+ secure, as you can control access via filesystem permissions.
117
+
118
+ Only one client can connect at a time. I don't think anyone needs multiple LC
119
+ connections to serve multiple instances of IRB to various clients, but if you
120
+ need it, let me know.
121
+
122
+ The README contains a slur against Lisp guys. Please stop hitting me with that PDP-10 manual. I love your language and the lambda tattoo on your chest.
123
+
124
+ Other than that, LiveConsole doesn't have any known bugs, but it is odd
125
+ software that also monkey-patches IRB, so they are likely to be there. Bug
126
+ reports and patches gratefully accepted.
127
+
128
+ == Credits
129
+
130
+ Pete Elmore, author -- (pete.elmore(a)gmail.com)
131
+
132
+ Roger D. Pack (http://betterlogic.com/roger/) provided patches and Windows
133
+ support
134
+
135
+ == Home page
136
+
137
+ http://debu.gs/live-console
data/doc/lc_example.rb ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'live_console' # load from gem
5
+
6
+ print <<-EOF
7
+ This is a demo program for LiveConsole. It starts a LiveConsole on the
8
+ specified port, and you can connect to it by using netcat or telnet to connect
9
+ to the specified port.
10
+ Usage:
11
+ #{$0} [port_number [value_for_$x]]
12
+ The default port is 3333, and $x is set by default to nil. Run this program,
13
+ and then in a different terminal, connect to it via netcat or telnet. You can
14
+ check that the value of $x is exactly what you set it to, and that you're
15
+ working inside this process, but there's not much to do inside the example
16
+ script. :)
17
+
18
+ EOF
19
+
20
+ port = ARGV.first.to_i
21
+ port = port.zero? ? 3333 : port
22
+ $x = ARGV[1]
23
+
24
+ lc = LiveConsole.new :socket, :port => port, :bind => binding
25
+ lc.start
26
+
27
+ puts "My PID is #{Process.pid}, " \
28
+ "I'm running on port #{port}, and $x = #{$x.inspect}"
29
+
30
+ oldx = $x
31
+ loop {
32
+ if $x != oldx
33
+ puts "The time is now #{Time.now.strftime('%R:%S')}.",
34
+ "The value of $x changed from #{oldx.inspect} to #{$x.inspect}."
35
+ oldx = $x
36
+ end
37
+ sleep 1
38
+ }
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'live_console'
5
+
6
+ default_path = "/tmp/lc_example_#{Process.uid}.sock"
7
+
8
+ print <<-EOF
9
+ This is a demo program for LiveConsole. It starts a LiveConsole at the
10
+ specified path, and you can connect to it by using netcat or telnet to connect
11
+ to the specified port.
12
+ Usage:
13
+ #{$0} [path_to_socket [value_for_$x]]
14
+ The default path is #{default_path}, and $x is set by default to nil.
15
+ Run this program, and then in a different terminal, connect to it via
16
+ the supplied udscat program or the BSD version of netcat.
17
+ EOF
18
+
19
+ path = ARGV.first
20
+ path = path.nil? ? default_path : path
21
+ $x = ARGV[1]
22
+
23
+ lc = LiveConsole.new :unix_socket, :path => path, :bind => binding
24
+ lc.start
25
+
26
+ puts "My PID is #{Process.pid}, " \
27
+ "I'm running on #{path}, and $x = #{$x.inspect}"
28
+
29
+ oldx = $x
30
+ loop {
31
+ if $x != oldx
32
+ puts "The time is now #{Time.now.strftime('%R:%S')}.",
33
+ "The value of $x changed from #{oldx.inspect} to #{$x.inspect}."
34
+ oldx = $x
35
+ end
36
+ sleep 1
37
+ }
@@ -0,0 +1,34 @@
1
+ class LiveConsole::IOMethods::SocketIO
2
+ DefaultOpts = {
3
+ :host => '127.0.0.1',
4
+ }.freeze
5
+ RequiredOpts = DefaultOpts.keys + [:port]
6
+
7
+ include LiveConsole::IOMethods::IOMethod
8
+
9
+ def start
10
+
11
+ begin
12
+ @server ||= TCPServer.new host, port
13
+ rescue => e
14
+ puts "unable to start live console server #{e}"
15
+ raise e
16
+ end
17
+
18
+ begin
19
+ IO.select([server])
20
+ self.raw_input = self.raw_output = server.accept
21
+ return true
22
+ rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EPROTO,
23
+ Errno::EINTR => e
24
+ select
25
+ retry
26
+ end
27
+ end
28
+
29
+ def stop
30
+ select
31
+ raw_input.close rescue nil
32
+ end
33
+
34
+ end
@@ -0,0 +1,31 @@
1
+ require 'socket'
2
+
3
+ class LiveConsole::IOMethods::UnixSocketIO
4
+ DefaultOpts = {
5
+ :mode => 0600,
6
+ :uid => Process.uid,
7
+ :gid => Process.gid,
8
+ }
9
+ RequiredOpts = DefaultOpts.keys + [:path]
10
+
11
+ include LiveConsole::IOMethods::IOMethod
12
+
13
+ def start
14
+ @server ||= UNIXServer.new path
15
+
16
+ begin
17
+ self.raw_input = self.raw_output = server.accept_nonblock
18
+ raw_input.sync = true
19
+ return true
20
+ rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EPROTO,
21
+ Errno::EINTR => e
22
+ select
23
+ retry
24
+ end
25
+ end
26
+
27
+ def stop
28
+ select
29
+ raw_input.close
30
+ end
31
+ end
@@ -0,0 +1,53 @@
1
+ module LiveConsole::IOMethods
2
+ List = []
3
+
4
+ Dir[File.join(File.dirname(__FILE__), 'io_methods', '*.rb')].each { |entry|
5
+ fname = entry.sub /\.rb$/, ''
6
+ classname = File.basename(entry, '.rb').capitalize.
7
+ gsub(/_(\w)/) { $1.upcase }.sub(/io$/i, 'IO').to_sym
8
+ mname = File.basename(fname).sub(/_io$/, '').to_sym
9
+
10
+ autoload classname, fname
11
+ List << mname
12
+
13
+ define_method(mname) {
14
+ const_get classname
15
+ }
16
+ }
17
+ List.freeze
18
+
19
+ extend self
20
+
21
+ module IOMethod
22
+ def initialize(opts)
23
+ self.opts = self.class::DefaultOpts.merge opts
24
+ unless missing_opts.empty?
25
+ raise ArgumentError, "Missing opts for " \
26
+ "#{self.class.name}: #{missing_opts.inspect}"
27
+ end
28
+ end
29
+
30
+ def missing_opts
31
+ self.class::RequiredOpts - opts.keys
32
+ end
33
+
34
+ def self.included(other)
35
+ other.instance_eval {
36
+ readers = [:opts, :raw_input, :raw_output]
37
+ attr_accessor *readers
38
+ private *readers.map { |r| (r.to_s + '=').to_sym }
39
+
40
+ other::RequiredOpts.each { |opt|
41
+ define_method(opt) { opts[opt] }
42
+ }
43
+ }
44
+ end
45
+
46
+ def select
47
+ IO.select [server], [], [], 1 if server
48
+ end
49
+
50
+ private
51
+ attr_accessor :server
52
+ end
53
+ end
@@ -0,0 +1,228 @@
1
+ # LiveConsole
2
+ # Pete Elmore (pete.elmore@gmail.com), 2007-10-18
3
+ # debu.gs/live-console
4
+ # See doc/LICENSE.
5
+
6
+ require 'irb'
7
+ require 'irb/frame'
8
+ require 'socket'
9
+
10
+ # LiveConsole provides a socket that can be connected to via netcat or telnet
11
+ # to use to connect to an IRB session inside a running process. It creates a
12
+ # thread that listens on the specified address/port or Unix Domain Socket path,
13
+ # and presents connecting clients with an IRB shell. Using this, you can
14
+ # execute code on a running instance of a Ruby process to inspect the state or
15
+ # even patch code on the fly. There is currently no readline support.
16
+ class LiveConsole
17
+ include Socket::Constants
18
+ autoload :IOMethods, 'live_console/io_methods'
19
+
20
+ attr_accessor :io_method, :io, :thread, :bind
21
+ private :io_method=, :io=, :thread=
22
+
23
+ # call-seq:
24
+ # # Bind a LiveConsole to localhost:3030 (only allow clients on this
25
+ # # machine to connect):
26
+ # LiveConsole.new :socket, :port => 3030
27
+ # # Accept connections from anywhere on port 3030. Ridiculously insecure:
28
+ # LiveConsole.new(:socket, :port => 3030, :host => '0.0.0.0')
29
+ # # Use a Unix Domain Socket (which is more secure) instead:
30
+ # LiveConsole.new(:unix_socket, :path => '/tmp/my_liveconsole.sock',
31
+ # :mode => 0600, :uid => Process.uid, :gid => Process.gid)
32
+ # # By default, the mode is 0600, and the uid and gid are those of the
33
+ # # current process. These three options are for the file's permissions.
34
+ # # You can also supply a binding for IRB's toplevel:
35
+ # LiveConsole.new(:unix_socket,
36
+ # :path => "/tmp/live_console_#{Process.pid}.sock", :bind => binding)
37
+ #
38
+ # Creates a new LiveConsole. You must next call LiveConsole#start when you
39
+ # want to spawn the thread to accept connections and start the console.
40
+ def initialize(io_method, opts = {})
41
+ self.io_method = io_method.to_sym
42
+ self.bind = opts.delete :bind
43
+ unless IOMethods::List.include?(self.io_method)
44
+ raise ArgumentError, "Unknown IO method: #{io_method}"
45
+ end
46
+
47
+ init_io opts
48
+ end
49
+
50
+ # LiveConsole#start spawns a thread to listen for, accept, and provide an
51
+ # IRB console to new connections. If a thread is already running, this
52
+ # method simply returns false; otherwise, it returns the new thread.
53
+ def start
54
+ if thread
55
+ if thread.alive?
56
+ return false
57
+ else
58
+ thread.join
59
+ self.thread = nil
60
+ end
61
+ end
62
+
63
+ self.thread = Thread.new {
64
+ loop {
65
+ Thread.pass
66
+ if io.start
67
+ irb_io = GenericIOMethod.new io.raw_input, io.raw_output
68
+ begin
69
+ IRB.start_with_io(irb_io, bind)
70
+ rescue Errno::EPIPE => e
71
+ # io.stop ??
72
+ end
73
+ io.stop
74
+ end
75
+ }
76
+ }
77
+ thread
78
+ end
79
+
80
+ # Ends the running thread, if it exists. Returns true if a thread was
81
+ # running, false otherwise.
82
+ def stop
83
+ if thread
84
+ if thread == Thread.current
85
+ self.thread = nil
86
+ Thread.current.exit!
87
+ end
88
+
89
+ thread.exit
90
+ if thread.join(0.1).nil?
91
+ thread.exit!
92
+ end
93
+ self.thread = nil
94
+ true
95
+ else
96
+ false
97
+ end
98
+ end
99
+
100
+ # Restarts. Useful for binding changes. Return value is the same as for
101
+ # LiveConsole#start.
102
+ def restart
103
+ r = lambda { stop; start }
104
+ if thread == Thread.current
105
+ Thread.new &r # Leaks a thread, but works.
106
+ else
107
+ r.call
108
+ end
109
+ end
110
+
111
+ private
112
+
113
+ def init_irb
114
+ return if @@irb_inited_already
115
+ IRB.setup nil
116
+ @@irb_inited_already = true
117
+ end
118
+
119
+ def init_io opts
120
+ self.io = IOMethods.send(io_method).new opts
121
+ end
122
+ end
123
+
124
+ # We need to make a couple of changes to the IRB module to account for using a
125
+ # weird I/O method and re-starting IRB from time to time.
126
+ module IRB
127
+ @inited = false
128
+
129
+ ARGV = []
130
+
131
+ # Overridden a la FXIrb to accomodate our needs.
132
+ def IRB.start_with_io(io, bind, &block)
133
+ unless @inited
134
+ setup '/dev/null'
135
+ IRB.parse_opts
136
+ IRB.load_modules
137
+ @inited = true
138
+ end
139
+
140
+ ws = IRB::WorkSpace.new(bind)
141
+ irb = Irb.new(ws, io, io)
142
+ bind ||= IRB::Frame.top(1) rescue TOPLEVEL_BINDING
143
+
144
+ @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
145
+ @CONF[:MAIN_CONTEXT] = irb.context
146
+ @CONF[:PROMPT_MODE] = :INF_RUBY
147
+
148
+ catch(:IRB_EXIT) {
149
+ begin
150
+ irb.eval_input
151
+ rescue StandardError => e
152
+ irb.print([e.to_s, e.backtrace].flatten.join("\n") + "\n")
153
+ retry
154
+ end
155
+ }
156
+ irb.print "\n"
157
+ end
158
+
159
+ class Context
160
+ # Fix an IRB bug; it ignores your output method.
161
+ def output *args
162
+ @output_method.print *args
163
+ end
164
+ end
165
+
166
+ class Irb
167
+ # Fix an IRB bug; it ignores your output method.
168
+ def printf(*args)
169
+ context.output(sprintf(*args))
170
+ end
171
+
172
+ # Fix an IRB bug; it ignores your output method.
173
+ def print(*args)
174
+ context.output *args
175
+ end
176
+ end
177
+ end
178
+
179
+ # The GenericIOMethod is a class that wraps I/O for IRB.
180
+ class GenericIOMethod < IRB::StdioInputMethod
181
+ # call-seq:
182
+ # GenericIOMethod.new io
183
+ # GenericIOMethod.new input, output
184
+ #
185
+ # Creates a GenericIOMethod, using either a single object for both input
186
+ # and output, or one object for input and another for output.
187
+ def initialize(input, output = nil)
188
+ @input, @output = input, output
189
+ @line = []
190
+ @line_no = 0
191
+ @stdin = input # fake it into thinking stdin is our input
192
+ end
193
+
194
+ attr_reader :input
195
+ def output
196
+ @output || input
197
+ end
198
+
199
+ def gets
200
+ output.print @prompt
201
+ output.flush
202
+ @line[@line_no += 1] = input.gets
203
+ # @io.flush # Not sure this is needed.
204
+ @line[@line_no]
205
+ end
206
+
207
+ # Returns the user input history.
208
+ def lines
209
+ @line.dup
210
+ end
211
+
212
+ def print(*a)
213
+ output.print *a
214
+ end
215
+
216
+ def file_name
217
+ input.inspect
218
+ end
219
+
220
+ def eof?
221
+ input.eof?
222
+ end
223
+
224
+ def close
225
+ input.close
226
+ output.close if @output
227
+ end
228
+ end
@@ -0,0 +1,9 @@
1
+ # This module houses a pile of informative constants for LiveConsole.
2
+ module LiveConsoleConfig
3
+ Authors = 'Pete Elmore'
4
+ Email = 'pete.elmore@gmail.com'
5
+ PkgName = 'live_console'
6
+ Version = '0.2.3'
7
+ URL = 'http://debu.gs/live-console'
8
+ Project = 'live-console'
9
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rogerdpack-live_console
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2.3
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pete Elmore
@@ -9,23 +9,36 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-22 00:00:00 -07:00
12
+ date: 2009-05-16 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
16
- description: A library to support adding a console to your running application.
17
- email:
18
- - pete.elmore@gmail.com
16
+ description:
17
+ email: pete.elmore@gmail.com
19
18
  executables:
20
19
  - udscat
21
20
  extensions: []
22
21
 
23
- extra_rdoc_files: []
24
-
25
- files: []
26
-
27
- has_rdoc: false
22
+ extra_rdoc_files:
23
+ - doc/LICENSE
24
+ - doc/README
25
+ - doc/lc_example.rb
26
+ - doc/lc_unix_example.rb
27
+ files:
28
+ - lib/live_console/io_methods/socket_io.rb
29
+ - lib/live_console/io_methods/unix_socket_io.rb
30
+ - lib/live_console/io_methods.rb
31
+ - lib/live_console.rb
32
+ - lib/live_console_config.rb
33
+ - doc/LICENSE
34
+ - doc/README
35
+ - doc/lc_example.rb
36
+ - doc/lc_unix_example.rb
37
+ - bin/udscat
38
+ - Rakefile
39
+ has_rdoc: true
28
40
  homepage: http://debu.gs/live-console
41
+ licenses:
29
42
  post_install_message:
30
43
  rdoc_options: []
31
44
 
@@ -45,10 +58,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
45
58
  version:
46
59
  requirements: []
47
60
 
48
- rubyforge_project: live-console
49
- rubygems_version: 1.2.0
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.5
50
63
  signing_key:
51
- specification_version: 3
52
- summary: A library to support adding a console to your running application.
64
+ specification_version: 2
65
+ summary: A library to support adding an irb console to your running application.
53
66
  test_files: []
54
67