rogerdpack-live_console 0.2.2.3 → 0.2.3

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/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