summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-03-24 08:52:35 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-03-24 08:52:35 +0000
commit35247a52ef719584a59ae9c518523f0ee825c8e3 (patch)
treee14e2a884d3c40a86f93b8dcb4ec144f510fe35a /lib
parent1727010a3abf84fd06f0e44d44b1b8ef6cde588e (diff)
990324
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_3@409 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r--lib/cgi-lib.rb96
-rw-r--r--lib/date2.rb208
-rw-r--r--lib/delegate.rb10
-rw-r--r--lib/mkmf.rb2
-rw-r--r--lib/monitor.rb370
-rw-r--r--lib/mutex_m.rb219
-rw-r--r--lib/profile.rb2
-rw-r--r--lib/rational.rb2
-rw-r--r--lib/sync.rb266
-rw-r--r--lib/telnet.rb313
-rw-r--r--lib/thread.rb4
-rw-r--r--lib/weakref.rb18
12 files changed, 624 insertions, 886 deletions
diff --git a/lib/cgi-lib.rb b/lib/cgi-lib.rb
index 12c8502..35b766e 100644
--- a/lib/cgi-lib.rb
+++ b/lib/cgi-lib.rb
@@ -27,14 +27,14 @@ and query.cookie has Hash class methods
== print HTTP header and HTML string to $>
require "cgi-lib.rb"
- CGI.print{
- CGI.tag("HTML"){
- CGI.tag("HEAD"){ CGI.tag("TITLE"){"TITLE"} } +
- CGI.tag("BODY"){
- CGI.tag("FORM", {"ACTION"=>"test.rb", "METHOD"=>"POST"}){
- CGI.tag("INPUT", {"TYPE"=>"submit", "VALUE"=>"submit"})
+ CGI::print{
+ CGI::tag("HTML"){
+ CGI::tag("HEAD"){ CGI::tag("TITLE"){"TITLE"} } +
+ CGI::tag("BODY"){
+ CGI::tag("FORM", {"ACTION"=>"test.rb", "METHOD"=>"POST"}){
+ CGI::tag("INPUT", {"TYPE"=>"submit", "VALUE"=>"submit"})
} +
- CGI.tag("HR")
+ CGI::tag("HR")
}
}
}
@@ -43,68 +43,68 @@ and query.cookie has Hash class methods
== make raw cookie string
require "cgi-lib.rb"
- cookie1 = CGI.cookie({'name' => 'name',
- 'value' => 'value',
- 'path' => 'path', # optional
- 'domain' => 'domain', # optional
- 'expires' => Time.now, # optional
- 'secure' => true # optional
- })
+ cookie1 = CGI::cookie({'name' => 'name',
+ 'value' => 'value',
+ 'path' => 'path', # optional
+ 'domain' => 'domain', # optional
+ 'expires' => Time.now, # optional
+ 'secure' => true # optional
+ })
- CGI.print("Content-Type: text/html", cookie1, cookie2){ "string" }
+ CGI::print("Content-Type: text/html", cookie1, cookie2){ "string" }
== print HTTP header and string to $>
require "cgi-lib.rb"
- CGI.print{ "string" }
- # == CGI.print("Content-Type: text/html"){ "string" }
- CGI.print("Content-Type: text/html", cookie1, cookie2){ "string" }
+ CGI::print{ "string" }
+ # == CGI::print("Content-Type: text/html"){ "string" }
+ CGI::print("Content-Type: text/html", cookie1, cookie2){ "string" }
=== NPH (no-parse-header) mode
require "cgi-lib.rb"
- CGI.print("nph"){ "string" }
- # == CGI.print("nph", "Content-Type: text/html"){ "string" }
- CGI.print("nph", "Content-Type: text/html", cookie1, cookie2){ "string" }
+ CGI::print("nph"){ "string" }
+ # == CGI::print("nph", "Content-Type: text/html"){ "string" }
+ CGI::print("nph", "Content-Type: text/html", cookie1, cookie2){ "string" }
== make HTML tag string
require "cgi-lib.rb"
- CGI.tag("element", {"attribute_name"=>"attribute_value"}){"content"}
+ CGI::tag("element", {"attribute_name"=>"attribute_value"}){"content"}
== make HTTP header string
require "cgi-lib.rb"
- CGI.header # == CGI.header("Content-Type: text/html")
- CGI.header("Content-Type: text/html", cookie1, cookie2)
+ CGI::header # == CGI::header("Content-Type: text/html")
+ CGI::header("Content-Type: text/html", cookie1, cookie2)
=== NPH (no-parse-header) mode
- CGI.header("nph") # == CGI.header("nph", "Content-Type: text/html")
- CGI.header("nph", "Content-Type: text/html", cookie1, cookie2)
+ CGI::header("nph") # == CGI::header("nph", "Content-Type: text/html")
+ CGI::header("nph", "Content-Type: text/html", cookie1, cookie2)
== escape url encode
require "cgi-lib.rb"
- url_encoded_string = CGI.escape("string")
+ url_encoded_string = CGI::escape("string")
== unescape url encoded
require "cgi-lib.rb"
- string = CGI.unescape("url encoded string")
+ string = CGI::unescape("url encoded string")
== escape HTML &"<>
require "cgi-lib.rb"
- CGI.escapeHTML("string")
+ CGI::escapeHTML("string")
=end
@@ -117,11 +117,6 @@ class CGI < SimpleDelegator
LF = "\012"
EOL = CR + LF
- # if running on Windows(IIS or PWS) then change cwd.
- if ENV['SERVER_SOFTWARE'] =~ /^Microsoft-/
- Dir.chdir(ENV['PATH_TRANSLATED'].sub(/[^\\]+$/, ''))
- end
-
# escape url encode
def escape(str)
str.gsub(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) }
@@ -160,12 +155,8 @@ class CGI < SimpleDelegator
case ENV['REQUEST_METHOD']
when "GET"
- # exception messages should be printed to stdout.
- STDERR.reopen($>)
ENV['QUERY_STRING'] or ""
when "POST"
- # exception messages should be printed to stdout.
- STDERR.reopen($>)
input.read Integer(ENV['CONTENT_LENGTH'])
else
read_from_cmdline
@@ -198,7 +189,7 @@ class CGI < SimpleDelegator
attr("cookie")
# make HTML tag string
- def CGI.tag(element, attributes = {})
+ def CGI::tag(element, attributes = {})
"<" + escapeHTML(element) + attributes.collect{|name, value|
" " + escapeHTML(name) + '="' + escapeHTML(value) + '"'
}.to_s + ">" +
@@ -206,7 +197,7 @@ class CGI < SimpleDelegator
end
# make raw cookie string
- def CGI.cookie(options)
+ def CGI::cookie(options)
"Set-Cookie: " + options['name'] + '=' + escape(options['value']) +
(options['domain'] ? '; domain=' + options['domain'] : '') +
(options['path'] ? '; path=' + options['path'] : '') +
@@ -215,7 +206,7 @@ class CGI < SimpleDelegator
end
# make HTTP header string
- def CGI.header(*options)
+ def CGI::header(*options)
if ENV['MOD_RUBY']
options.each{|option|
option.sub(/(.*?): (.*)/){
@@ -238,32 +229,31 @@ class CGI < SimpleDelegator
end
# print HTTP header and string to $>
- def CGI.print(*options)
- $>.print CGI.header(*options) + yield.to_s
+ def CGI::print(*options)
+ $>.print CGI::header(*options) + yield.to_s
end
# print message to $>
- def CGI.message(message, title = "", header = ["Content-Type: text/html"])
+ def CGI::message(message, title = "", header = ["Content-Type: text/html"])
if message.kind_of?(Hash)
title = message['title']
header = message['header']
message = message['body']
end
- CGI.print(*header){
- CGI.tag("HTML"){
- CGI.tag("HEAD"){ CGI.tag("TITLE"){ title } } +
- CGI.tag("BODY"){ message }
+ CGI::print(*header){
+ CGI::tag("HTML"){
+ CGI::tag("HEAD"){ CGI.tag("TITLE"){ title } } +
+ CGI::tag("BODY"){ message }
}
}
TRUE
end
# print error message to $> and exit
- def CGI.error
- CGI.message({'title'=>'ERROR', 'body'=>
- CGI.tag("PRE"){
- "ERROR: " + CGI.tag("STRONG"){ escapeHTML($!.to_s) } + "\n" +
- escapeHTML($@.join("\n"))
+ def CGI::error
+ CGI::message({'title'=>'ERROR', 'body'=>
+ CGI::tag("PRE"){
+ "ERROR: " + CGI::tag("STRONG"){ escapeHTML($!.to_s) } + "\n" + escapeHTML($@.join("\n"))
}
})
exit
diff --git a/lib/date2.rb b/lib/date2.rb
index 6e87824..a1045a9 100644
--- a/lib/date2.rb
+++ b/lib/date2.rb
@@ -1,107 +1,138 @@
# date.rb: Written by Tadayoshi Funaba 1998, 1999
-# $Id: date.rb,v 1.5 1999/02/06 08:51:56 tadf Exp $
+# $Id: date.rb,v 1.7 1999/03/06 02:05:59 tadf Exp $
class Date
include Comparable
- MONTHNAMES = [ nil, 'January', 'February', 'March', 'April', 'May', 'June',
- 'July', 'August', 'September', 'October', 'November', 'December' ]
+ MONTHNAMES = [ nil, 'January', 'February', 'March',
+ 'April', 'May', 'June', 'July', 'August',
+ 'September', 'October', 'November', 'December' ]
- DAYNAMES = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
- 'Friday', 'Saturday' ]
+ DAYNAMES = [ 'Sunday', 'Monday', 'Tuesday',
+ 'Wednesday', 'Thursday', 'Friday', 'Saturday' ]
ITALY = 2299161 # Oct 15, 1582
ENGLAND = 2361222 # Sept 14, 1752
- def Date.civil_to_jd(y, m, d, gs = true)
- if m <= 2 then
- y -= 1
- m += 12
+ class << self
+
+ def civil_to_jd(y, m, d, gs=true)
+ if m <= 2
+ y -= 1
+ m += 12
+ end
+ a = (y / 100).to_i
+ b = 2 - a + (a / 4).to_i
+ jd = (365.25 * (y + 4716)).to_i +
+ (30.6001 * (m + 1)).to_i +
+ d + b - 1524
+ unless
+ (if gs.kind_of? Numeric then jd >= gs else gs end)
+ jd -= b
+ end
+ jd
end
- a = (y / 100).to_i
- b = 2 - a + (a / 4).to_i
- jd = (365.25 * (y + 4716)).to_i +
- (30.6001 * (m + 1)).to_i +
- d + b - 1524
- unless
- (if gs.kind_of? Numeric then jd >= gs else gs end) then
- jd -= b
+
+ def jd_to_civil(jd, gs=true)
+ unless
+ (if gs.kind_of? Numeric then jd >= gs else gs end)
+ a = jd
+ else
+ x = ((jd - 1867216.25) / 36524.25).to_i
+ a = jd + 1 + x - (x / 4).to_i
+ end
+ b = a + 1524
+ c = ((b - 122.1) / 365.25).to_i
+ d = (365.25 * c).to_i
+ e = ((b - d) / 30.6001).to_i
+ dom = b - d - (30.6001 * e).to_i
+ if e <= 13
+ m = e - 1
+ y = c - 4716
+ else
+ m = e - 13
+ y = c - 4715
+ end
+ return y, m, dom
end
- jd
- end
- def Date.jd_to_civil(jd, gs = true)
- unless
- (if gs.kind_of? Numeric then jd >= gs else gs end) then
- a = jd
- else
- x = ((jd - 1867216.25) / 36524.25).to_i
- a = jd + 1 + x - (x / 4).to_i
+ def ordinal_to_jd(y, d, gs=true)
+ civil_to_jd(y, 1, d, gs)
end
- b = a + 1524
- c = ((b - 122.1) / 365.25).to_i
- d = (365.25 * c).to_i
- e = ((b - d) / 30.6001).to_i
- dom = b - d - (30.6001 * e).to_i
- if e <= 13 then
- m = e - 1
- y = c - 4716
- else
- m = e - 13
- y = c - 4715
+
+ def jd_to_ordinal(jd, gs=true)
+ y, *_ = jd_to_civil(jd, gs)
+ ns = if gs.kind_of? Numeric then jd >= gs else gs end
+ pl = civil_to_jd(y - 1, 12, 31, ns)
+ doy = jd - pl
+ return y, doy
end
- return y, m, dom
- end
- def Date.mjd_to_jd(mjd)
- mjd + 2400000.5
- end
+ def mjd_to_jd(mjd)
+ mjd + 2400000.5
+ end
- def Date.jd_to_mjd(jd)
- jd - 2400000.5
- end
+ def jd_to_mjd(jd)
+ jd - 2400000.5
+ end
- def Date.tjd_to_jd(tjd)
- tjd + 2440000.5
- end
+ def tjd_to_jd(tjd)
+ tjd + 2440000.5
+ end
- def Date.jd_to_tjd(jd)
- jd - 2440000.5
- end
+ def jd_to_tjd(jd)
+ jd - 2440000.5
+ end
- def Date.julian_leap? (y)
- y % 4 == 0
- end
+ def julian_leap? (y)
+ y % 4 == 0
+ end
- def Date.gregorian_leap? (y)
- y % 4 == 0 and y % 100 != 0 or y % 400 == 0
- end
+ def gregorian_leap? (y)
+ y % 4 == 0 and y % 100 != 0 or y % 400 == 0
+ end
- def Date.leap? (y)
- Date.gregorian_leap?(y)
- end
+ alias_method :leap?, :gregorian_leap?
- def initialize(jd = 0, gs = ITALY)
- @jd, @gs = jd, gs
- end
+ def exist3? (y, m, d, gs=true)
+ jd = civil_to_jd(y, m, d, gs)
+ if [y, m, d] == jd_to_civil(jd, gs)
+ jd
+ end
+ end
- def Date.exist? (y, m, d, gs = true)
- jd = Date.civil_to_jd(y, m, d, gs)
- if [y, m, d] == Date.jd_to_civil(jd, gs) then
- jd
+ alias_method :exist?, :exist3?
+
+ def new3(y=-4712, m=1, d=1, gs=ITALY)
+ unless jd = exist3?(y, m, d, gs)
+ fail ArgumentError, 'invalid date'
+ end
+ new(jd, gs)
+ end
+
+ def exist2? (y, d, gs=true)
+ jd = ordinal_to_jd(y, d, gs)
+ if [y, d] == jd_to_ordinal(jd, gs)
+ jd
+ end
end
- end
- def Date.new3(y = -4712, m = 1, d = 1, gs = ITALY)
- unless jd = Date.exist?(y, m, d, gs) then
- fail ArgumentError, 'invalid date'
+ def new2(y=-4712, d=1, gs=ITALY)
+ unless jd = exist2?(y, d, gs)
+ fail ArgumentError, 'invalid date'
+ end
+ new(jd, gs)
end
- Date.new(jd, gs)
+
+ def today(gs=ITALY)
+ new(civil_to_jd(*(Time.now.to_a[3..5].reverse << gs)), gs)
+ end
+
end
- def Date.today(gs = ITALY)
- Date.new(Date.civil_to_jd(*(Time.now.to_a[3..5].reverse << gs)), gs)
+ def initialize(jd=0, gs=ITALY)
+ @jd, @gs = jd, gs
end
def jd
@@ -109,19 +140,19 @@ class Date
end
def mjd
- def self.mjd; @mjd end
+ def self.mjd() @mjd end
@mjd = Date.jd_to_mjd(@jd)
end
def tjd
- def self.tjd; @tjd end
+ def self.tjd() @tjd end
@tjd = Date.jd_to_tjd(@jd)
end
def civil
- def self.year; @year end
- def self.mon; @mon end
- def self.mday; @mday end
+ def self.year() @year end
+ def self.mon() @mon end
+ def self.mday() @mday end
@year, @mon, @mday = Date.jd_to_civil(@jd, @gs)
end
@@ -133,10 +164,9 @@ class Date
end
def yday
- def self.yday; @yday end
- ns = if @gs.kind_of? Numeric then @jd >= @gs else @gs end
- jd = Date.civil_to_jd(year - 1, 12, 31, ns)
- @yday = @jd - jd
+ def self.yday() @yday end
+ _, @yday = Date.jd_to_ordinal(@jd, @gs)
+ @yday
end
def mon
@@ -150,12 +180,12 @@ class Date
end
def wday
- def self.wday; @wday end
+ def self.wday() @wday end
@wday = (@jd + 1) % 7
end
def leap?
- def self.leap?; @leap_p end
+ def self.leap?() @leap_p end
ns = if @gs.kind_of? Numeric then @jd >= @gs else @gs end
jd = Date.civil_to_jd(year, 2, 28, ns)
@leap_p = Date.jd_to_civil(jd + 1, ns)[1] == 2
@@ -214,4 +244,12 @@ class Date
format('%04d-%02d-%02d', year, mon, mday)
end
+ def _dump(limit)
+ Marshal.dump([@jd, @gs], -1)
+ end
+
+ def Date._load(str)
+ Date.new(*Marshal.load(str))
+ end
+
end
diff --git a/lib/delegate.rb b/lib/delegate.rb
index 0771f2f..29f2a5d 100644
--- a/lib/delegate.rb
+++ b/lib/delegate.rb
@@ -34,14 +34,8 @@ class Delegator
begin
__getobj__.__send__(:#{method}, *args, &block)
rescue Exception
- c = -caller(0).size
- if /:in `__getobj__'$/ =~ $@[c-1] #`
- n = 1
- else
- c -= 1
- n = 2
- end
- $@[c,n] = nil
+ $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
+ $@.delete_if{|s| /^\\(eval\\):/ =~ s}
raise
end
end
diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 52b4ed2..df03b12 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -37,7 +37,7 @@ $libdir += "/"+CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
$archdir = $libdir+"/"+CONFIG["arch"]
$install = CONFIG["INSTALL_PROGRAM"]
$install_data = CONFIG["INSTALL_DATA"]
-if $install !~ /^\// then
+if $install =~ %r!^[^\s/]+/! then
$install = CONFIG["srcdir"]+"/"+$install
$install_data = CONFIG["srcdir"]+"/"+$install_data
end
diff --git a/lib/monitor.rb b/lib/monitor.rb
index 81fe8f2..75d9c35 100644
--- a/lib/monitor.rb
+++ b/lib/monitor.rb
@@ -1,184 +1,162 @@
-## monitor.rb
+=begin
-# Author: Shugo Maeda <shugo@po.aianet.ne.jp>
-# Version: $Revision: 0.1 $
+monitor.rb
+Author: Shugo Maeda <shugo@netlab.co.jp>
+Version: 1.2.1
-# USAGE:
-#
-# foo = Foo.new
-# foo.extend(MonitorMixin)
-# cond = foo.new_cond
-#
-# thread1:
-# foo.synchronize {
-# ...
-# cond.wait_until { foo.done? }
-# ...
-# }
-#
-# thread2:
-# foo.synchronize {
-# foo.do_something
-# cond.signal
-# }
+USAGE:
-# ATTENTION:
-#
-# If you include MonitorMixin and override `initialize', you should
-# call `super'.
-# If you include MonitorMixin to built-in classes, you should override
-# `new' to call `mon_initialize'.
+ foo = Foo.new
+ foo.extend(MonitorMixin)
+ cond = foo.new_cond
-## Code:
-
-require "final"
+ thread1:
+ foo.synchronize {
+ ...
+ cond.wait_until { foo.done? }
+ ...
+ }
-module MonitorMixin
-
- RCS_ID = %q$Id: monitor.rb,v 0.1 1998/03/01 08:40:18 shugo Exp shugo $
+ thread2:
+ foo.synchronize {
+ foo.do_something
+ cond.signal
+ }
+
+=end
- module Primitive
-
- include MonitorMixin
-
- MON_OWNER_TABLE = {}
- MON_COUNT_TABLE = {}
- MON_ENTERING_QUEUE_TABLE = {}
- MON_WAITING_QUEUE_TABLE = {}
-
- FINALIZER = Proc.new { |id|
- MON_OWNER_TABLE.delete(id)
- MON_COUNT_TABLE.delete(id)
- MON_ENTERING_QUEUE_TABLE.delete(id)
- MON_WAITING_QUEUE_TABLE.delete(id)
- }
+module MonitorMixin
+ module Accessible
+ protected
+ attr_accessor :mon_owner, :mon_count
+ attr_reader :mon_entering_queue, :mon_waiting_queue
+ end
- def self.extend_object(obj)
- super(obj)
- obj.mon_initialize
- end
-
+ module Initializable
+ protected
def mon_initialize
- MON_OWNER_TABLE[id] = nil
- MON_COUNT_TABLE[id] = 0
- MON_ENTERING_QUEUE_TABLE[id] = []
- MON_WAITING_QUEUE_TABLE[id] = []
- ObjectSpace.define_finalizer(self, FINALIZER)
- end
-
- def mon_owner
- return MON_OWNER_TABLE[id]
+ @mon_owner = nil
+ @mon_count = 0
+ @mon_entering_queue = []
+ @mon_waiting_queue = []
end
+ end
+
+ class ConditionVariable
+ class Timeout < Exception; end
- def mon_count
- return MON_COUNT_TABLE[id]
- end
+ include Accessible
- def mon_entering_queue
- return MON_ENTERING_QUEUE_TABLE[id]
+ def wait(timeout = nil)
+ if @monitor.mon_owner != Thread.current
+ raise ThreadError, "current thread not owner"
+ end
+
+ Thread.critical = true
+ count = @monitor.mon_count
+ @monitor.mon_count = 0
+ @monitor.mon_owner = nil
+ if @monitor.mon_waiting_queue.empty?
+ t = @monitor.mon_entering_queue.shift
+ else
+ t = @monitor.mon_waiting_queue.shift
+ end
+ t.wakeup if t
+ @waiters.push(Thread.current)
+
+ if timeout
+ t = Thread.current
+ timeout_thread = Thread.start {
+ sleep(timeout)
+ t.raise(Timeout.new)
+ }
+ end
+ begin
+ Thread.stop
+ rescue Timeout
+ @waiters.delete(Thread.current)
+ ensure
+ if timeout && timeout_thread.alive?
+ Thread.kill(timeout_thread)
+ end
+ end
+
+ Thread.critical = true
+ while @monitor.mon_owner &&
+ @monitor.mon_owner != Thread.current
+ @monitor.mon_waiting_queue.push(Thread.current)
+ Thread.stop
+ Thread.critical = true
+ end
+ @monitor.mon_owner = Thread.current
+ @monitor.mon_count = count
+ Thread.critical = false
end
- def mon_waiting_queue
- return MON_WAITING_QUEUE_TABLE[id]
+ def wait_while
+ while yield
+ wait
+ end
end
- def set_mon_owner(val)
- return MON_OWNER_TABLE[id] = val
+ def wait_until
+ until yield
+ wait
+ end
end
- def set_mon_count(val)
- return MON_COUNT_TABLE[id] = val
+ def signal
+ if @monitor.mon_owner != Thread.current
+ raise ThreadError, "current thread not owner"
+ end
+ Thread.critical = true
+ t = @waiters.shift
+ t.wakeup if t
+ Thread.critical = false
+ Thread.pass
end
- private :mon_count, :mon_entering_queue, :mon_waiting_queue,
- :set_mon_owner, :set_mon_count
- end
-
- module NonPrimitive
-
- include MonitorMixin
-
- attr_reader :mon_owner, :mon_count,
- :mon_entering_queue, :mon_waiting_queue
-
- def self.extend_object(obj)
- super(obj)
- obj.mon_initialize
- end
-
- def mon_initialize
- @mon_owner = nil
- @mon_count = 0
- @mon_entering_queue = []
- @mon_waiting_queue = []
+ def broadcast
+ if @monitor.mon_owner != Thread.current
+ raise ThreadError, "current thread not owner"
+ end
+ Thread.critical = true
+ for t in @waiters
+ t.wakeup
+ end
+ @waiters.clear
+ Thread.critical = false
+ Thread.pass
end
- def set_mon_owner(val)
- @mon_owner = val
+ def count_waiters
+ return @waiters.length
end
- def set_mon_count(val)
- @mon_count = val
+ private
+ def initialize(monitor)
+ @monitor = monitor
+ @waiters = []
end
-
- private :mon_count, :mon_entering_queue, :mon_waiting_queue,
- :set_mon_owner, :set_mon_count
end
- def self.extendable_module(obj)
- if Fixnum === obj or TrueClass === obj or FalseClass === obj or
- NilClass === obj
- raise TypeError, "MonitorMixin can't extend #{obj.type}"
- else
- begin
- obj.instance_eval("@mon_owner")
- return NonPrimitive
- rescue TypeError
- return Primitive
- end
- end
- end
+ include Accessible
+ include Initializable
+ extend Initializable
def self.extend_object(obj)
- obj.extend(extendable_module(obj))
- end
-
- def self.includable_module(klass)
- if klass.instance_of?(Module)
- return NonPrimitive
- end
- begin
- dummy = klass.new
- return extendable_module(dummy)
- rescue ArgumentError
- if klass.singleton_methods.include?("new")
- return Primitive
- else
- return NonPrimitive
- end
- rescue NameError
- raise TypeError, "#{klass} can't include MonitorMixin"
- end
- end
-
- def self.append_features(klass)
- mod = includable_module(klass)
- klass.module_eval("include mod")
- end
-
- def initialize(*args)
- super
- mon_initialize
+ super(obj)
+ obj.mon_initialize
end
def try_mon_enter
result = false
Thread.critical = true
if mon_owner.nil?
- set_mon_owner(Thread.current)
+ self.mon_owner = Thread.current
end
if mon_owner == Thread.current
- set_mon_count(mon_count + 1)
+ self.mon_count += 1
result = true
end
Thread.critical = false
@@ -192,8 +170,8 @@ module MonitorMixin
Thread.stop
Thread.critical = true
end
- set_mon_owner(Thread.current)
- set_mon_count(mon_count + 1)
+ self.mon_owner = Thread.current
+ self.mon_count += 1
Thread.critical = false
end
@@ -202,9 +180,9 @@ module MonitorMixin
raise ThreadError, "current thread not owner"
end
Thread.critical = true
- set_mon_count(mon_count - 1)
+ self.mon_count -= 1
if mon_count == 0
- set_mon_owner(nil)
+ self.mon_owner = nil
if mon_waiting_queue.empty?
t = mon_entering_queue.shift
else
@@ -225,93 +203,16 @@ module MonitorMixin
end
end
alias synchronize mon_synchronize
-
- class ConditionVariable
- def initialize(monitor)
- @monitor = monitor
- @waiters = []
- end
-
- def wait
- if @monitor.mon_owner != Thread.current
- raise ThreadError, "current thread not owner"
- end
-
- @monitor.instance_eval(<<MON_EXIT)
- Thread.critical = true
- _count = mon_count
- set_mon_count(0)
- set_mon_owner(nil)
- if mon_waiting_queue.empty?
- t = mon_entering_queue.shift
- else
- t = mon_waiting_queue.shift
- end
- t.wakeup if t
- Thread.critical = false
-MON_EXIT
-
- Thread.critical = true
- @waiters.push(Thread.current)
- Thread.stop
-
- @monitor.instance_eval(<<MON_ENTER)
- Thread.critical = true
- while mon_owner != nil && mon_owner != Thread.current
- mon_waiting_queue.push(Thread.current)
- Thread.stop
- Thread.critical = true
- end
- set_mon_owner(Thread.current)
- set_mon_count(_count)
- Thread.critical = false
-MON_ENTER
- end
-
- def wait_while
- while yield
- wait
- end
- end
-
- def wait_until
- until yield
- wait
- end
- end
-
- def signal
- if @monitor.mon_owner != Thread.current
- raise ThreadError, "current thread not owner"
- end
- Thread.critical = true
- t = @waiters.shift
- t.wakeup if t
- Thread.critical = false
- Thread.pass
- end
-
- def broadcast
- if @monitor.mon_owner != Thread.current
- raise ThreadError, "current thread not owner"
- end
- Thread.critical = true
- for t in @waiters
- t.wakeup
- end
- @waiters.clear
- Thread.critical = false
- Thread.pass
- end
-
- def count_waiters
- return @waiters.length
- end
- end
def new_cond
return ConditionVariable.new(self)
end
+
+private
+ def initialize(*args)
+ super
+ mon_initialize
+ end
end
class Monitor
@@ -322,4 +223,7 @@ class Monitor
alias owner mon_owner
end
-## monitor.rb ends here
+# Local variables:
+# mode: Ruby
+# tab-width: 8
+# End:
diff --git a/lib/mutex_m.rb b/lib/mutex_m.rb
index dd92ff9..ed773b7 100644
--- a/lib/mutex_m.rb
+++ b/lib/mutex_m.rb
@@ -15,51 +15,24 @@
# extended object can be handled like Mutex
#
-require "finalize"
-
module Mutex_m
- def Mutex_m.extendable_module(obj)
- if Fixnum === obj or TRUE === obj or FALSE === obj or nil == obj
- raise TypeError, "Mutex_m can't extend to this class(#{obj.type})"
- else
- begin
- obj.instance_eval "@mu_locked"
- For_general_object
- rescue TypeError
- For_primitive_object
- end
- end
- end
-
- def Mutex_m.includable_module(cl)
- begin
- dummy = cl.new
- Mutex_m.extendable_module(dummy)
- rescue NameError
- # if new is not defined, cl must be Data.
- For_primitive_object
+ def Mutex_m.append_features(cl)
+ super
+ unless cl.instance_of?(Module)
+ cl.module_eval %q{
+ alias locked? mu_locked?
+ alias lock mu_lock
+ alias unlock mu_unlock
+ alias try_lock mu_try_lock
+ alias synchronize mu_synchronize
+ }
end
- end
-
- def Mutex_m.extend_class(cl)
- return super if cl.instance_of?(Module)
-
- # do nothing for Modules
- # make aliases and include the proper module.
- real = includable_module(cl)
- cl.module_eval %q{
- include real
-
- alias locked? mu_locked?
- alias lock mu_lock
- alias unlock mu_unlock
- alias try_lock mu_try_lock
- alias synchronize mu_synchronize
- }
+ return self
end
def Mutex_m.extend_object(obj)
- obj.extend(Mutex_m.extendable_module(obj))
+ super
+ obj.mu_extended
end
def mu_extended
@@ -76,6 +49,7 @@ module Mutex_m
alias synchronize mu_synchronize
end"
end
+ initialize
end
# locking
@@ -88,131 +62,50 @@ module Mutex_m
end
end
- # internal class
- module For_general_object
- include Mutex_m
-
- def For_general_object.extend_object(obj)
- super
- obj.mu_extended
- end
-
- def mu_extended
- super
- @mu_waiting = []
- @mu_locked = FALSE;
- end
-
- def mu_locked?
- @mu_locked
- end
-
- def mu_try_lock
- result = FALSE
- Thread.critical = TRUE
- unless @mu_locked
- @mu_locked = TRUE
- result = TRUE
- end
- Thread.critical = FALSE
- result
- end
-
- def mu_lock
- while (Thread.critical = TRUE; @mu_locked)
- @mu_waiting.push Thread.current
- Thread.stop
- end
+ def mu_locked?
+ @mu_locked
+ end
+
+ def mu_try_lock
+ result = FALSE
+ Thread.critical = TRUE
+ unless @mu_locked
@mu_locked = TRUE
- Thread.critical = FALSE
- self
+ result = TRUE
end
-
- def mu_unlock
- return unless @mu_locked
- Thread.critical = TRUE
- wait = @mu_waiting
- @mu_waiting = []
- @mu_locked = FALSE
- Thread.critical = FALSE
- for w in wait
- w.run
- end
- self
- end
-
+ Thread.critical = FALSE
+ result
end
-
- module For_primitive_object
- include Mutex_m
- Mu_Locked = Hash.new
-
- def For_primitive_object.extend_object(obj)
- super
-
- obj.mu_extended
- Finalizer.add(obj, For_primitive_object, :mu_finalize)
- end
-
- def mu_extended
- super
- initialize
- end
-
- def For_primitive_object.mu_finalize(id)
- Thread.critical = TRUE
- if wait = Mu_Locked.delete(id)
- Thread.critical = FALSE
- for w in wait
- w.run
- end
- else
- Thread.critical = FALSE
- end
- self
- end
-
- def mu_locked?
- Mu_Locked.key?(self.id)
- end
-
- def mu_try_lock
- Thread.critical = TRUE
- if Mu_Locked.key?(self.id)
- ret = FALSE
- else
- Mu_Locked[self.id] = []
- Finalizer.add(self, For_primitive_object, :mu_finalize)
- ret = TRUE
- end
- Thread.critical = FALSE
- ret
- end
-
- def mu_lock
- while (Thread.critical = TRUE; w = Mu_Locked[self.id])
- w.push Thread.current
- Thread.stop
- end
- Mu_Locked[self.id] = []
- Finalizer.add(self, For_primitive_object, :mu_finalize)
- Thread.critical = FALSE
- self
- end
-
- def mu_unlock
- Thread.critical = TRUE
- if wait = Mu_Locked.delete(self.id)
- Finalizer.delete(self, For_primitive_object, :mu_finalize)
- Thread.critical = FALSE
- for w in wait
- w.run
- end
- else
- Thread.critical = FALSE
- end
- self
- end
+
+ def mu_lock
+ while (Thread.critical = TRUE; @mu_locked)
+ @mu_waiting.push Thread.current
+ Thread.stop
+ end
+ @mu_locked = TRUE
+ Thread.critical = FALSE
+ self
+ end
+
+ def mu_unlock
+ return unless @mu_locked
+ Thread.critical = TRUE
+ wait = @mu_waiting
+ @mu_waiting = []
+ @mu_locked = FALSE
+ Thread.critical = FALSE
+ for w in wait
+ w.run
+ end
+ self
+ end
+
+ private
+
+ def initialize(*args)
+ ret = super
+ @mu_waiting = []
+ @mu_locked = FALSE;
+ return ret
end
end
-
diff --git a/lib/profile.rb b/lib/profile.rb
index 3634b5b..e4b1b4b 100644
--- a/lib/profile.rb
+++ b/lib/profile.rb
@@ -22,7 +22,7 @@ module Profiler__
else
name += "."
end
- data = [0, 0, 0, name+id.id2name]
+ data = [0.0, 0.0, 0.0, name+id.id2name]
MAP[id] = data
end
data[0] += 1
diff --git a/lib/rational.rb b/lib/rational.rb
index 1282f56..f976cf0 100644
--- a/lib/rational.rb
+++ b/lib/rational.rb
@@ -77,7 +77,7 @@ class Rational < Numeric
@denominator = den
else
@numerator = num.to_i
- @denoninator = den.to_i
+ @denominator = den.to_i
end
end
diff --git a/lib/sync.rb b/lib/sync.rb
index dc54626..f1410af 100644
--- a/lib/sync.rb
+++ b/lib/sync.rb
@@ -44,8 +44,6 @@ unless defined? Thread
fail "Thread not available for this ruby interpreter"
end
-require "final"
-
module Sync_m
RCS_ID='-$Header$-'
@@ -78,51 +76,27 @@ module Sync_m
end
end
- # include and extend initialize methods.
- def Sync_m.extendable_module(obj)
- if Fixnum === obj or TRUE === obj or FALSE === obj or nil == obj
- raise TypeError, "Sync_m can't extend to this class(#{obj.type})"
- else
- begin
- obj.instance_eval "@sync_locked"
- For_general_object
- rescue TypeError
- For_primitive_object
- end
- end
- end
-
- def Sync_m.includable_module(cl)
- begin
- dummy = cl.new
- Sync_m.extendable_module(dummy)
- rescue NameError
- # if new is not defined, cl must be Data.
- For_primitive_object
+ def Sync_m.append_features(cl)
+ super
+ unless cl.instance_of?(Module)
+ # do nothing for Modules
+ # make aliases and include the proper module.
+ cl.module_eval %q{
+ alias locked? sync_locked?
+ alias shared? sync_shared?
+ alias exclusive? sync_exclusive?
+ alias lock sync_lock
+ alias unlock sync_unlock
+ alias try_lock sync_try_lock
+ alias synchronize sync_synchronize
+ }
end
- end
-
- def Sync_m.extend_class(cl)
- return super if cl.instance_of?(Module)
-
- # do nothing for Modules
- # make aliases and include the proper module.
- real = includable_module(cl)
- cl.module_eval %q{
- include real
-
- alias locked? sync_locked?
- alias shared? sync_shared?
- alias exclusive? sync_exclusive?
- alias lock sync_lock
- alias unlock sync_unlock
- alias try_lock sync_try_lock
- alias synchronize sync_synchronize
- }
+ return self
end
def Sync_m.extend_object(obj)
- obj.extend(Sync_m.extendable_module(obj))
+ super
+ obj.sync_extended
end
def sync_extended
@@ -143,6 +117,7 @@ module Sync_m
alias synchronize sync_synchronize
end"
end
+ initialize
end
# accessing
@@ -162,16 +137,16 @@ module Sync_m
def sync_try_lock(mode = EX)
return unlock if sync_mode == UN
- Thread.critical = TRUE
+ Thread.critical = true
ret = sync_try_lock_sub(sync_mode)
- Thread.critical = FALSE
+ Thread.critical = false
ret
end
def sync_lock(m = EX)
return unlock if m == UN
- until (Thread.critical = TRUE; sync_try_lock_sub(m))
+ until (Thread.critical = true; sync_try_lock_sub(m))
if sync_sh_locker[Thread.current]
sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
sync_sh_locker.delete(Thread.current)
@@ -180,23 +155,23 @@ module Sync_m
end
Thread.stop
end
- Thread.critical = FALSE
+ Thread.critical = false
self
end
def sync_unlock(m = EX)
- Thread.critical = TRUE
+ Thread.critical = true
if sync_mode == UN
- Thread.critical = FALSE
+ Thread.critical = false
Err::UnknownLocker.Fail(Thread.current)
end
m = sync_mode if m == EX and sync_mode == SH
- runnable = FALSE
+ runnable = false
case m
when UN
- Thread.critical = FALSE
+ Thread.critical = false
Err::UnknownLocker.Fail(Thread.current)
when EX
@@ -208,7 +183,7 @@ module Sync_m
else
self.sync_mode = UN
end
- runnable = TRUE
+ runnable = true
end
else
Err::UnknownLocker.Fail(Thread.current)
@@ -222,7 +197,7 @@ module Sync_m
sync_sh_locker.delete(Thread.current)
if sync_sh_locker.empty? and sync_ex_count == 0
self.sync_mode = UN
- runnable = TRUE
+ runnable = true
end
end
end
@@ -235,7 +210,7 @@ module Sync_m
end
wait = sync_upgrade_waiting
self.sync_upgrade_waiting = []
- Thread.critical = FALSE
+ Thread.critical = false
for w, v in wait
w.run
@@ -243,17 +218,46 @@ module Sync_m
else
wait = sync_waiting
self.sync_waiting = []
- Thread.critical = FALSE
+ Thread.critical = false
for w in wait
w.run
end
end
end
- Thread.critical = FALSE
+ Thread.critical = false
self
end
+ def sync_synchronize(mode = EX)
+ sync_lock(mode)
+ begin
+ yield
+ ensure
+ sync_unlock
+ end
+ end
+
+ attr :sync_mode, true
+ attr :sync_waiting, true
+ attr :sync_upgrade_waiting, true
+ attr :sync_sh_locker, true
+ attr :sync_ex_locker, true
+ attr :sync_ex_count, true
+
+ private
+
+ def initialize(*args)
+ ret = super
+ @sync_mode = UN
+ @sync_waiting = []
+ @sync_upgrade_waiting = []
+ @sync_sh_locker = Hash.new
+ @sync_ex_locker = nil
+ @sync_ex_count = 0
+ return ret
+ end
+
def sync_try_lock_sub(m)
case m
when SH
@@ -261,18 +265,18 @@ module Sync_m
when UN
self.sync_mode = m
sync_sh_locker[Thread.current] = 1
- ret = TRUE
+ ret = true
when SH
count = 0 unless count = sync_sh_locker[Thread.current]
sync_sh_locker[Thread.current] = count + 1
- ret = TRUE
+ ret = true
when EX
# in EX mode, lock will upgrade to EX lock
if sync_ex_locker == Thread.current
self.sync_ex_count = sync_ex_count + 1
- ret = TRUE
+ ret = true
else
- ret = FALSE
+ ret = false
end
end
when EX
@@ -281,157 +285,29 @@ module Sync_m
self.sync_mode = m
self.sync_ex_locker = Thread.current
self.sync_ex_count = 1
- ret = TRUE
+ ret = true
elsif sync_mode == EX && sync_ex_locker == Thread.current
self.sync_ex_count = sync_ex_count + 1
- ret = TRUE
+ ret = true
else
- ret = FALSE
+ ret = false
end
else
- Thread.critical = FALSE
+ Thread.critical = false
Err::LockModeFailer.Fail mode
end
return ret
end
- private :sync_try_lock_sub
-
- def sync_synchronize(mode = EX)
- sync_lock(mode)
- begin
- yield
- ensure
- sync_unlock
- end
- end
-
- # internal class
- module For_primitive_object
- include Sync_m
-
- LockState = Struct.new("LockState",
- :mode,
- :waiting,
- :upgrade_waiting,
- :sh_locker,
- :ex_locker,
- :ex_count)
-
- Sync_Locked = Hash.new
-
- def For_primitive_object.extend_object(obj)
- super
- obj.sync_extended
- # Changed to use `final.rb'.
- # Finalizer.add(obj, For_primitive_object, :sync_finalize)
- ObjectSpace.define_finalizer(obj) do |id|
- For_primitive_object.sync_finalize(id)
- end
- end
-
- def initialize
- super
- Sync_Locked[id] = LockState.new(UN, [], [], Hash.new, nil, 0 )
- self
- end
-
- def sync_extended
- super
- initialize
- end
-
- def For_primitive_object.sync_finalize(id)
- wait = Sync_Locked.delete(id)
- # need not to free waiting
- end
-
- def sync_mode
- Sync_Locked[id].mode
- end
- def sync_mode=(value)
- Sync_Locked[id].mode = value
- end
-
- def sync_waiting
- Sync_Locked[id].waiting
- end
- def sync_waiting=(v)
- Sync_Locked[id].waiting = v
- end
-
- def sync_upgrade_waiting
- Sync_Locked[id].upgrade_waiting
- end
- def sync_upgrade_waiting=(v)
- Sync_Locked[id].upgrade_waiting = v
- end
-
- def sync_sh_locker
- Sync_Locked[id].sh_locker
- end
- def sync_sh_locker=(v)
- Sync_Locked[id].sh_locker = v
- end
-
- def sync_ex_locker
- Sync_Locked[id].ex_locker
- end
- def sync_ex_locker=(value)
- Sync_Locked[id].ex_locker = value
- end
-
- def sync_ex_count
- Sync_Locked[id].ex_count
- end
- def sync_ex_count=(value)
- Sync_Locked[id].ex_count = value
- end
-
- end
-
- module For_general_object
- include Sync_m
-
- def For_general_object.extend_object(obj)
- super
- obj.sync_extended
- end
-
- def initialize
- super
- @sync_mode = UN
- @sync_waiting = []
- @sync_upgrade_waiting = []
- @sync_sh_locker = Hash.new
- @sync_ex_locker = nil
- @sync_ex_count = 0
- self
- end
-
- def sync_extended
- super
- initialize
- end
-
- attr :sync_mode, TRUE
-
- attr :sync_waiting, TRUE
- attr :sync_upgrade_waiting, TRUE
- attr :sync_sh_locker, TRUE
- attr :sync_ex_locker, TRUE
- attr :sync_ex_count, TRUE
-
- end
end
Synchronizer_m = Sync_m
class Sync
- Sync_m.extend_class self
- #include Sync_m
+ include Sync_m
+
+ private
def initialize
super
end
-
end
Synchronizer = Sync
diff --git a/lib/telnet.rb b/lib/telnet.rb
index 10a528e..098cbc9 100644
--- a/lib/telnet.rb
+++ b/lib/telnet.rb
@@ -1,8 +1,142 @@
=begin
-telnet.rb ver0.161 1999/02/03
+= simple telnet cliant library
+
+telnet.rb ver0.162 1999/03/18
+
Wakou Aoyama <wakou@fsinet.or.jp>
+
+= methods
+
+== new (make new Telnet object)
+
+ host = Telnet.new({"Binmode" => FALSE, # default: FALSE
+ "Host" => "localhost", # default: "localhost"
+ "Output_log" => "output_log", # default: not output
+ "Dump_log" => "dump_log", # default: not output
+ "Port" => 23, # default: 23
+ "Prompt" => /[$%#>] \Z/, # default: /[$%#>] \Z/
+ "Telnetmode" => TRUE, # default: TRUE
+ "Timeout" => 10, # default: 10
+ "Waittime" => 0, # default: 0
+ "Proxy" => proxy}) # default: nil
+ # proxy is Telnet or TCPsocket object
+
+Telnet object has socket class methods.
+
+if set "Telnetmode" option FALSE. not TELNET command interpretation.
+"Waittime" is time to confirm "Prompt". There is a possibility that
+the same character as "Prompt" is included in the data, and, when
+the network or the host is very heavy, the value is enlarged.
+
+
+== waitfor (wait for match)
+
+ line = host.waitfor(/match/)
+ line = host.waitfor({"Match" => /match/,
+ "String" => "string",
+ "Timeout" => secs})
+
+if set "String" option. Match = Regexp.new(quote(string))
+
+
+=== realtime output
+
+ host.waitfor(/match/){|c| print c }
+ host.waitfor({"Match" => /match/,
+ "String" => "string",
+ "Timeout" => secs}){|c| print c}
+
+of cource, set sync=TRUE or flush is necessary.
+
+
+== cmd (send string and wait prompt)
+
+ line = host.cmd("string")
+ line = host.cmd({"String" => "string",
+ "Prompt" => /[$%#>] \Z/,
+ "Timeout" => 10})
+
+
+=== realtime output
+
+ host.cmd("string"){|c| print c }
+ host.cmd({"String" => "string",
+ "Prompt" => /[$%#>] \Z/,
+ "Timeout" => 10}){|c| print c }
+
+of cource, set sync=TRUE or flush is necessary.
+
+
+== print (send string)
+
+ host.print("string")
+
+
+== telnetmode (turn telnet command interpretation)
+
+ host.telnetmode # turn on/off
+ host.telnetmode(TRUE) # on
+ host.telnetmode(FALSE) # off
+
+
+== binmode (toggle newline translation)
+
+ host.binmode # turn TRUE/FALSE
+ host.binmode(TRUE) # no translate newline
+ host.binmode(FALSE) # translate newline
+
+
+== login
+
+ host.login("username", "password")
+ host.login({"Name" => "username",
+ "Password" => "password",
+ "Prompt" => /[$%#>] \Z/,
+ "Timeout" => 10})
+
+
+=== realtime output
+
+ host.login("username", "password"){|c| print c }
+ host.login({"Name" => "username",
+ "Password" => "password",
+ "Prompt" => /[$%#>] \Z/,
+ "Timeout" => 10}){|c| print c }
+
+of cource, set sync=TRUE or flush is necessary.
+
+
+= sample
+
+== login and send command
+
+ localhost = Telnet.new({"Host" => "localhost",
+ "Timeout" => 10,
+ "Prompt" => /[$%#>] \Z/})
+ localhost.login("username", "password"){|c| print c }
+ localhost.cmd("command"){|c| print c }
+ localhost.close
+
+
+== checks a POP server to see if you have mail
+
+ pop = Telnet.new({"Host" => "your_destination_host_here",
+ "Port" => 110,
+ "Telnetmode" => FALSE,
+ "Prompt" => /^\+OK/})
+ pop.cmd("user " + "your_username_here"){|c| print c}
+ pop.cmd("pass " + "your_password_here"){|c| print c}
+ pop.cmd("list"){|c| print c}
+
+
+= history
+
+ver0.162 1999/03/17
+add "Proxy" option
+required timeout.rb
+
ver0.161 1999/02/03
select --> IO::select
@@ -44,128 +178,16 @@ add realtime output.
ver0.10 1998/04/13
first release.
-== make new Telnet object
-host = Telnet.new({"Binmode" => FALSE, default: FALSE
- "Host" => "localhost", default: "localhost"
- "Output_log" => "output_log", default: not output
- "Dump_log" => "dump_log", default: not output
- "Port" => 23, default: 23
- "Prompt" => /[$%#>] \Z/, default: /[$%#>] \Z/
- "Telnetmode" => TRUE, default: TRUE
- "Timeout" => 10, default: 10
- "Waittime" => 0}) default: 0
-
-if set "Telnetmode" option FALSE. not TELNET command interpretation.
-"Waittime" is time to confirm "Prompt". There is a possibility that
-the same character as "Prompt" is included in the data, and, when
-the network or the host is very heavy, the value is enlarged.
-
-== wait for match
-line = host.waitfor(/match/)
-line = host.waitfor({"Match" => /match/,
- "String" => "string",
- "Timeout" => secs})
-if set "String" option. Match = Regexp.new(quote(string))
-
-realtime output. of cource, set sync=TRUE or flush is necessary.
-host.waitfor(/match/){|c| print c }
-host.waitfor({"Match" => /match/,
- "String" => "string",
- "Timeout" => secs}){|c| print c}
-
-== send string and wait prompt
-line = host.cmd("string")
-line = host.cmd({"String" => "string",
- "Prompt" => /[$%#>] \Z/,
- "Timeout" => 10})
-
-realtime output. of cource, set sync=TRUE or flush is necessary.
-host.cmd("string"){|c| print c }
-host.cmd({"String" => "string",
- "Prompt" => /[$%#>] \Z/,
- "Timeout" => 10}){|c| print c }
-
-== send string
-host.print("string")
-
-== turn telnet command interpretation
-host.telnetmode # turn on/off
-host.telnetmode(TRUE) # on
-host.telnetmode(FALSE) # off
-
-== toggle newline translation
-host.binmode # turn TRUE/FALSE
-host.binmode(TRUE) # no translate newline
-host.binmode(FALSE) # translate newline
-
-== login
-host.login("username", "password")
-host.login({"Name" => "username",
- "Password" => "password",
- "Prompt" => /[$%#>] \Z/,
- "Timeout" => 10})
-
-realtime output. of cource, set sync=TRUE or flush is necessary.
-host.login("username", "password"){|c| print c }
-host.login({"Name" => "username",
- "Password" => "password",
- "Prompt" => /[$%#>] \Z/,
- "Timeout" => 10}){|c| print c }
-
-and Telnet object has socket class methods
-
-== sample
-localhost = Telnet.new({"Host" => "localhost",
- "Timeout" => 10,
- "Prompt" => /[$%#>] \Z/})
-localhost.login("username", "password"){|c| print c }
-localhost.cmd("command"){|c| print c }
-localhost.close
-
-== sample 2
-checks a POP server to see if you have mail.
-
-pop = Telnet.new({"Host" => "your_destination_host_here",
- "Port" => 110,
- "Telnetmode" => FALSE,
- "Prompt" => /^\+OK/})
-pop.cmd("user " + "your_username_here"){|c| print c}
-pop.cmd("pass " + "your_password_here"){|c| print c}
-pop.cmd("list"){|c| print c}
-
=end
require "socket"
require "delegate"
require "thread"
-
-class TimeOut < Exception
-end
+require "timeout"
+TimeOut = TimeoutError
class Telnet < SimpleDelegator
- def timeout(sec)
- is_timeout = FALSE
- begin
- x = Thread.current
- y = Thread.start {
- sleep sec
- if x.alive?
- #print "timeout!\n"
- x.raise TimeOut, "timeout"
- end
- }
- begin
- yield
- rescue TimeOut
- is_timeout = TRUE
- end
- ensure
- Thread.kill y if y && y.alive?
- end
- is_timeout
- end
-
IAC = 255.chr # interpret as command:
DONT = 254.chr # you are not to use option
DO = 253.chr # please, you use option
@@ -259,32 +281,45 @@ class Telnet < SimpleDelegator
@dumplog.binmode
end
- message = "Trying " + @options["Host"] + "...\n"
- STDOUT.write(message)
- @log.write(message) if @options.include?("Output_log")
- @dumplog.write(message) if @options.include?("Dump_log")
+ if @options.include?("Proxy")
+ if @options["Proxy"].kind_of?(Telnet)
+ @sock = @options["Proxy"].sock
+ elsif @options["Proxy"].kind_of?(TCPsocket)
+ @sock = @options["Proxy"]
+ else
+ raise "Error; Proxy is Telnet or TCPSocket object."
+ end
+ else
+ message = "Trying " + @options["Host"] + "...\n"
+ STDOUT.write(message)
+ @log.write(message) if @options.include?("Output_log")
+ @dumplog.write(message) if @options.include?("Dump_log")
- is_timeout = timeout(@options["Timeout"]){
begin
- @sock = TCPsocket.open(@options["Host"], @options["Port"])
+ timeout(@options["Timeout"]){
+ @sock = TCPsocket.open(@options["Host"], @options["Port"])
+ }
+ rescue TimeoutError
+ raise TimeOut, "timed-out; opening of the host"
rescue
@log.write($! + "\n") if @options.include?("Output_log")
@dumplog.write($! + "\n") if @options.include?("Dump_log")
raise
end
- }
- raise TimeOut, "timed-out; opening of the host" if is_timeout
- @sock.sync = TRUE
- @sock.binmode
+ @sock.sync = TRUE
+ @sock.binmode
- message = "Connected to " + @options["Host"] + ".\n"
- STDOUT.write(message)
- @log.write(message) if @options.include?("Output_log")
- @dumplog.write(message) if @options.include?("Dump_log")
+ message = "Connected to " + @options["Host"] + ".\n"
+ STDOUT.write(message)
+ @log.write(message) if @options.include?("Output_log")
+ @dumplog.write(message) if @options.include?("Dump_log")
+ end
super(@sock)
end
+ attr :sock
+
def telnetmode(mode = 'turn')
if 'turn' == mode
@options["Telnetmode"] = @options["Telnetmode"] ? FALSE : TRUE
@@ -347,12 +382,12 @@ class Telnet < SimpleDelegator
end
def waitfor(options)
- timeout = @options["Timeout"]
+ time_out = @options["Timeout"]
waittime = @options["Waittime"]
if options.kind_of?(Hash)
prompt = options["Prompt"] if options.include?("Prompt")
- timeout = options["Timeout"] if options.include?("Timeout")
+ time_out = options["Timeout"] if options.include?("Timeout")
waittime = options["Waittime"] if options.include?("Waittime")
prompt = Regexp.new( Regexp.quote(options["String"]) ) if
options.include?("String")
@@ -363,7 +398,7 @@ class Telnet < SimpleDelegator
line = ''
until(not IO::select([@sock], nil, nil, waittime) and prompt === line)
raise TimeOut, "timed-out; wait for the next data" if
- not IO::select([@sock], nil, nil, timeout)
+ not IO::select([@sock], nil, nil, time_out)
buf = ''
begin
buf = @sock.sysread(1024 * 1024)
@@ -399,13 +434,13 @@ class Telnet < SimpleDelegator
end
def cmd(options)
- match = @options["Prompt"]
- timeout = @options["Timeout"]
+ match = @options["Prompt"]
+ time_out = @options["Timeout"]
if options.kind_of?(Hash)
- string = options["String"]
- match = options["Match"] if options.include?("Match")
- timeout = options["Timeout"] if options.include?("Timeout")
+ string = options["String"]
+ match = options["Match"] if options.include?("Match")
+ time_out = options["Timeout"] if options.include?("Timeout")
else
string = options
end
@@ -413,9 +448,9 @@ class Telnet < SimpleDelegator
IO::select(nil, [@sock])
print(string)
if iterator?
- waitfor({"Prompt" => match, "Timeout" => timeout}){|c| yield c }
+ waitfor({"Prompt" => match, "Timeout" => time_out}){|c| yield c }
else
- waitfor({"Prompt" => match, "Timeout" => timeout})
+ waitfor({"Prompt" => match, "Timeout" => time_out})
end
end
diff --git a/lib/thread.rb b/lib/thread.rb
index ec75144..4e6d765 100644
--- a/lib/thread.rb
+++ b/lib/thread.rb
@@ -144,6 +144,10 @@ class Queue
@que.length == 0
end
+ def clear
+ @que.replace([])
+ end
+
def length
@que.length
end
diff --git a/lib/weakref.rb b/lib/weakref.rb
index d53aa15..d969553 100644
--- a/lib/weakref.rb
+++ b/lib/weakref.rb
@@ -2,11 +2,12 @@
#
# Usage:
# foo = Object.new
-# foo.hash
+# foo = Object.new
+# p foo.to_s # original's class
# foo = WeakRef.new(foo)
-# foo.hash
+# p foo.to_s # should be same class
# ObjectSpace.garbage_collect
-# foo.hash # => Raises WeakRef::RefError (because original GC'ed)
+# p foo.to_s # should raise exception (recycled)
require "delegate"
@@ -18,9 +19,11 @@ class WeakRef<Delegator
ID_MAP = {}
ID_REV_MAP = {}
ObjectSpace.add_finalizer(lambda{|id|
- rid = ID_MAP[id]
- if rid
- ID_REV_MAP[rid] = nil
+ rids = ID_MAP[id]
+ if rids
+ for rid in rids
+ ID_REV_MAP[rid] = nil
+ end
ID_MAP[id] = nil
end
rid = ID_REV_MAP[id]
@@ -35,7 +38,8 @@ class WeakRef<Delegator
@__id = orig.__id__
ObjectSpace.call_finalizer orig
ObjectSpace.call_finalizer self
- ID_MAP[@__id] = self.__id__
+ ID_MAP[@__id] = [] unless ID_MAP[@__id]
+ ID_MAP[@__id].concat self.__id__
ID_REV_MAP[self.id] = @__id
end