summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-11-07 09:01:34 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-11-07 09:01:34 +0000
commit2f12c07c76c38a377e98555f1af738a8aa12f112 (patch)
tree0ca8dfde034e3a4837a4d4c7b5536a0bf3540e03
parent566c793d9b032ae1bc03340a10c4b5d1dcd116a7 (diff)
* dir.c (my_getcwd): do not rely on MAXPATHLEN.
* eval.c (rb_yield_0): should not call rb_f_block_given_p(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_6@1814 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog13
-rw-r--r--configure.in2
-rw-r--r--dir.c27
-rw-r--r--eval.c9
-rw-r--r--file.c8
-rw-r--r--lib/resolv.rb352
-rw-r--r--parse.y33
-rw-r--r--string.c2
-rw-r--r--version.h4
9 files changed, 381 insertions, 69 deletions
diff --git a/ChangeLog b/ChangeLog
index f54066fc30..d50bcaa570 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,18 @@
+Tue Nov 6 14:38:48 2001 Yukihiro Matsumoto <[email protected]>
+
+ * dir.c (my_getcwd): do not rely on MAXPATHLEN.
+
+Mon Nov 5 17:09:55 2001 Yukihiro Matsumoto <[email protected]>
+
+ * eval.c (rb_yield_0): should not call rb_f_block_given_p().
+
Sat Nov 3 22:28:51 2001 Keiju Ishitsuka <[email protected]>
+
+ * forwardable.rb: change raise to Kernel::raise
+
* matrix.rb (Matrix#column_vectors, Matrix#row_vectors): ditto bug.
this bug report and fix by [email protected].
- * forwardable.rb: change raise to Kernel::raise
-
Thu Nov 1 14:08:42 2001 Yukihiro Matsumoto <[email protected]>
* bignum.c (rb_big_aref): idx may be a Bignum.
diff --git a/configure.in b/configure.in
index 1ab6e509d0..07e2ecad3b 100644
--- a/configure.in
+++ b/configure.in
@@ -528,7 +528,7 @@ if test "$with_dln_a_out" != yes; then
LDFLAGS="-Wl,-E"
rb_cv_dlopen=yes;;
solaris*) if test "$GCC" = yes; then
- LDSHARED='$(CC) -Wl,-G'
+ LDSHARED='$(CC) -Wl,-G -shared'
`$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null && LDFLAGS="-Wl,-E"
else
LDSHARED='ld -G'
diff --git a/dir.c b/dir.c
index 621418b797..9feb48faf0 100644
--- a/dir.c
+++ b/dir.c
@@ -419,20 +419,29 @@ dir_s_chdir(argc, argv, obj)
return INT2FIX(0);
}
+static char *
+my_getcwd()
+{
+ int size = MAXPATHLEN;
+ char *buf = xmalloc(size);
+
+ while (!getcwd(buf, size)) {
+ if (errno != ERANGE) rb_sys_fail(buf);
+ size *= 2;
+ buf = xrealloc(buf, size);
+ }
+ return buf;
+}
+
static VALUE
dir_s_getwd(dir)
VALUE dir;
{
- char path[MAXPATHLEN];
-
-#ifdef HAVE_GETCWD
- if (getcwd(path, sizeof(path)) == 0) rb_sys_fail(path);
-#else
- extern char *getwd();
- if (getwd(path) == 0) rb_sys_fail(path);
-#endif
+ char *path = my_getcwd();
+ VALUE cwd = rb_tainted_str_new2(path);
- return rb_tainted_str_new2(path);
+ free(path);
+ return cwd;
}
static VALUE
diff --git a/eval.c b/eval.c
index d7c8c967d4..8ae640fabf 100644
--- a/eval.c
+++ b/eval.c
@@ -3502,7 +3502,8 @@ rb_iterator_p()
static VALUE
rb_f_block_given_p()
{
- if (ruby_frame->prev && ruby_frame->prev->iter) return Qtrue;
+ if (ruby_frame->prev && ruby_frame->prev->iter && ruby_block)
+ return Qtrue;
return Qfalse;
}
@@ -3521,8 +3522,8 @@ rb_yield_0(val, self, klass, acheck)
int state;
static unsigned serial = 1;
- if (!(rb_block_given_p() || rb_f_block_given_p()) || !ruby_block) {
- rb_raise(rb_eLocalJumpError, "yield called out of block");
+ if (!rb_block_given_p()) {
+ rb_raise(rb_eLocalJumpError, "no block given");
}
PUSH_VARS();
@@ -4470,7 +4471,7 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper)
v = rb_ary_new4(argc,argv);
else
v = rb_ary_new2(0);
- local_vars[node->nd_rest] = v;
+ ruby_scope->local_vars[node->nd_rest] = v;
}
}
}
diff --git a/file.c b/file.c
index ce6fa7ae63..8b0104469f 100644
--- a/file.c
+++ b/file.c
@@ -2118,10 +2118,10 @@ rb_path_check(path)
if (pend) *pend = '\0';
safe = path_check_1(p);
- if (!safe) {
- if (pend) *pend = sep;
- return 0;
- }
+ if (!safe) {
+ if (pend) *pend = sep;
+ return 0;
+ }
if (!pend) break;
*pend = sep;
p = pend + 1;
diff --git a/lib/resolv.rb b/lib/resolv.rb
index 68b41c65bf..5caaa1af5f 100644
--- a/lib/resolv.rb
+++ b/lib/resolv.rb
@@ -1,3 +1,176 @@
+=begin
+= resolv library
+resolv.rb is a resolver library written in Ruby.
+Since it is written in Ruby, it is thread-aware.
+I.e. it can resolv many hostnames concurrently.
+
+It is possible to lookup various resources of DNS using DNS module directly.
+
+== example
+ Resolv.getaddress("www.ruby-lang.org")
+ Resolv.getname("210.251.121.214").to_s
+ Resolv::DNS.new.getresources("www.ruby-lang.org", Resolv::DNS::Resource::IN::A).collect {|r| r.address}
+ Resolv::DNS.new.getresources("ruby-lang.org", Resolv::DNS::Resource::IN::MX).collect {|r| [r.exchange.to_s, r.preference]}
+
+== Resolv module
+
+=== module methods
+--- Resolv.getaddress(name)
+--- Resolv.getaddresses(name)
+--- Resolv.each_address(name) {|address| ...}
+ They lookups IP addresses of ((|name|)) which represents a hostname
+ as a string.
+
+ getaddress returns first entry of lookupped addresses.
+ getaddresses returns lookupped addresses.
+ each_address iterates over lookupped addresses.
+
+--- Resolv.getname(address)
+--- Resolv.getnames(address)
+--- Resolv.each_name(address) {|name| ...}
+ lookups hostnames of ((|address|)) which represents IP address as a string.
+
+ getname returns first entry of lookupped names.
+ getnames returns lookupped names.
+ each_names iterates over lookupped names.
+
+== Resolv::Hosts class
+hostname resolver using /etc/hosts format.
+
+=== class methods
+--- Resolv::Hosts.new(hosts='/etc/hosts')
+
+=== methods
+--- Resolv::Hosts#getaddress(name)
+--- Resolv::Hosts#getaddresses(name)
+--- Resolv::Hosts#each_address(name) {|address| ...}
+ address lookup methods.
+
+--- Resolv::Hosts#getname(address)
+--- Resolv::Hosts#getnames(address)
+--- Resolv::Hosts#each_name(address) {|name| ...}
+ hostnames lookup methods.
+
+== Resolv::DNS class
+DNS stub resolver.
+
+=== class methods
+--- Resolv::DNS.new(resolv_conf='/etc/resolv.conf')
+
+=== methods
+--- Resolv::DNS#getaddress(name)
+--- Resolv::DNS#getaddresses(name)
+--- Resolv::DNS#each_address(name) {|address| ...}
+ address lookup methods.
+
+ ((|name|)) must be a instance of Resolv::Name or String. Lookupped
+ address is represented as an instance of Resolv::IPv4 or Resolv::IPv6.
+
+--- Resolv::DNS#getname(address)
+--- Resolv::DNS#getnames(address)
+--- Resolv::DNS#each_name(address) {|name| ...}
+ hostnames lookup methods.
+
+ ((|address|)) must be a instance of Resolv::IPv4, Resolv::IPv6 or String.
+ Lookupped name is represented as an instance of Resolv::Name.
+
+--- Resolv::DNS#getresource(name, typeclass)
+--- Resolv::DNS#getresources(name, typeclass)
+--- Resolv::DNS#each_resource(name, typeclass) {|resource| ...}
+ They lookup DNS resources of ((|name|)).
+ ((|name|)) must be a instance of Resolv::Name or String.
+
+ ((|typeclass|)) should be one of follows:
+ * Resolv::DNS::Resource::IN::ANY
+ * Resolv::DNS::Resource::IN::NS
+ * Resolv::DNS::Resource::IN::CNAME
+ * Resolv::DNS::Resource::IN::SOA
+ * Resolv::DNS::Resource::IN::HINFO
+ * Resolv::DNS::Resource::IN::MINFO
+ * Resolv::DNS::Resource::IN::MX
+ * Resolv::DNS::Resource::IN::TXT
+ * Resolv::DNS::Resource::IN::ANY
+ * Resolv::DNS::Resource::IN::A
+ * Resolv::DNS::Resource::IN::WKS
+ * Resolv::DNS::Resource::IN::PTR
+ * Resolv::DNS::Resource::IN::AAAA
+
+ Lookupped resource is represented as an instance of (a subclass of)
+ Resolv::DNS::Resource.
+
+== Resolv::DNS::Resource::IN::NS class
+--- name
+== Resolv::DNS::Resource::IN::CNAME class
+--- name
+== Resolv::DNS::Resource::IN::SOA class
+--- mname
+--- rname
+--- serial
+--- refresh
+--- retry
+--- expire
+--- minimum
+== Resolv::DNS::Resource::IN::HINFO class
+--- cpu
+--- os
+== Resolv::DNS::Resource::IN::MINFO class
+--- rmailbx
+--- emailbx
+== Resolv::DNS::Resource::IN::MX class
+--- preference
+--- exchange
+== Resolv::DNS::Resource::IN::TXT class
+--- data
+== Resolv::DNS::Resource::IN::A class
+--- address
+== Resolv::DNS::Resource::IN::WKS class
+--- address
+--- protocol
+--- bitmap
+== Resolv::DNS::Resource::IN::PTR class
+--- name
+== Resolv::DNS::Resource::IN::AAAA class
+--- address
+
+== Resolv::DNS::Name class
+
+=== class methods
+--- Resolv::DNS::Name.create(name)
+
+=== methods
+--- Resolv::DNS::Name#to_s
+
+== Resolv::DNS::Resource class
+
+== Resolv::IPv4 class
+=== class methods
+--- Resolv::IPv4.create(address)
+
+=== methods
+--- Resolv::IPv4#to_s
+--- Resolv::IPv4#to_name
+
+=== constants
+--- Resolv::IPv4::Regex
+ regular expression for IPv4 address.
+
+== Resolv::IPv6 class
+=== class methods
+--- Resolv::IPv6.create(address)
+
+=== methods
+--- Resolv::IPv6#to_s
+--- Resolv::IPv6#to_name
+
+=== constants
+--- Resolv::IPv6::Regex
+ regular expression for IPv6 address.
+
+== Bugs
+NIS is not supported.
+
+=end
+
require 'socket'
require 'fcntl'
require 'timeout'
@@ -8,35 +181,76 @@ class Resolv
DefaultResolver.getaddress(name)
end
+ def self.getaddresses(name)
+ DefaultResolver.getaddresses(name)
+ end
+
+ def self.each_address(name, &block)
+ DefaultResolver.each_address(name, &block)
+ end
+
def self.getname(address)
DefaultResolver.getname(address)
end
+ def self.getnames(address)
+ DefaultResolver.getnames(address)
+ end
+
+ def self.each_name(address, &proc)
+ DefaultResolver.each_name(address, &proc)
+ end
+
def initialize(resolvers=[Hosts.new, DNS.new])
@resolvers = resolvers
end
def getaddress(name)
- return name if AddressRegex =~ name
- rs = @resolvers.dup
- begin
- r = rs.shift
- return r.getaddress(name)
- rescue ResolvError
- retry unless rs.empty?
- raise
+ each_address(name) {|address| return address}
+ raise ResolvError.new("no address for #{name}")
+ end
+
+ def getaddresses(name)
+ ret = []
+ each_address(name) {|address| ret << address}
+ return ret
+ end
+
+ def each_address(name)
+ if AddressRegex =~ name
+ yield name
+ return
end
+ yielded = false
+ @resolvers.each {|r|
+ r.each_address(name) {|address|
+ yield address.to_s
+ yielded = true
+ }
+ return if yielded
+ }
end
def getname(address)
- rs = @resolvers.dup
- begin
- r = rs.shift
- return r.getname(address)
- rescue ResolvError
- retry unless rs.empty?
- raise
- end
+ each_name(address) {|name| return name}
+ raise ResolvError.new("no name for #{address}")
+ end
+
+ def getnames(address)
+ ret = []
+ each_name(address) {|name| ret << name}
+ return ret
+ end
+
+ def each_name(address)
+ yielded = false
+ @resolvers.each {|r|
+ r.each_name(address) {|name|
+ yield name.to_s
+ yielded = true
+ }
+ return if yielded
+ }
end
class ResolvError < StandardError
@@ -79,20 +293,38 @@ class Resolv
end
def getaddress(name)
+ each_address(name) {|address| return address}
+ raise ResolvError.new("#{@filename} has no name: #{name}")
+ end
+
+ def getaddresses(name)
+ ret = []
+ each_address(name) {|address| ret << address}
+ return ret
+ end
+
+ def each_address(name, &proc)
lazy_initialize
if @name2addr.include?(name)
- return @name2addr[name][0]
- else
- raise ResolvError.new("#{@filename} has no name: #{name}")
+ @name2addr[name].each(&proc)
end
end
def getname(address)
+ each_name(address) {|name| return name}
+ raise ResolvError.new("#{@filename} has no address: #{address}")
+ end
+
+ def getnames(address)
+ ret = []
+ each_name(address) {|name| ret << name}
+ return ret
+ end
+
+ def each_name(address, &proc)
lazy_initialize
if @addr2name.include?(address)
- return @addr2name[address][0]
- else
- raise ResolvError.new("#{@filename} has no address: #{address}")
+ @addr2name[address].each(&proc)
end
end
end
@@ -127,10 +359,32 @@ class Resolv
end
def getaddress(name)
- return getresource(name, Resource::IN::A).address
+ each_address(name) {|address| return address}
+ raise ResolvError.new("DNS result has no information for #{name}")
+ end
+
+ def getaddresses(name)
+ ret = []
+ each_address(name) {|address| ret << address}
+ return ret
+ end
+
+ def each_address(name)
+ each_resource(name, Resource::IN::A) {|resource| yield resource.address}
end
def getname(address)
+ each_name(address) {|name| return name}
+ raise ResolvError.new("DNS result has no information for #{address}")
+ end
+
+ def getnames(address)
+ ret = []
+ each_name(address) {|name| ret << name}
+ return ret
+ end
+
+ def each_name(address)
case address
when Name
ptr = address
@@ -141,10 +395,21 @@ class Resolv
else
raise ResolvError.new("cannot interpret as address: #{address}")
end
- return getresource(ptr, Resource::IN::PTR).name
+ each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name}
end
def getresource(name, typeclass)
+ each_resource(name, typeclass) {|resource| return resource}
+ raise ResolvError.new("DNS result has no information for #{name}")
+ end
+
+ def getresources(name, typeclass)
+ ret = []
+ each_resource(name, typeclass) {|resource| ret << resource}
+ return ret
+ end
+
+ def each_resource(name, typeclass, &proc)
lazy_initialize
q = Queue.new
senders = {}
@@ -162,7 +427,8 @@ class Resolv
timeout(tout) { reply, reply_name = q.pop }
case reply.rcode
when RCode::NoError
- return extract_resource(reply, reply_name, typeclass)
+ extract_resources(reply, reply_name, typeclass, &proc)
+ return
when RCode::NXDomain
raise Config::NXDomain.new(reply_name)
else
@@ -174,27 +440,35 @@ class Resolv
end
end
- def extract_resource(msg, name, typeclass)
+ def extract_resources(msg, name, typeclass)
+ if typeclass < Resource::ANY
+ n0 = Name.create(name)
+ msg.each_answer {|n, ttl, data|
+ yield data if n0 == n
+ }
+ end
+ yielded = false
n0 = Name.create(name)
msg.each_answer {|n, ttl, data|
if n0 == n
case data
when typeclass
- return data
+ yield data
+ yielded = true
when Resource::CNAME
n0 = data.name
end
end
}
+ return if yielded
msg.each_answer {|n, ttl, data|
if n0 == n
case data
when typeclass
- return data
+ yield data
end
end
}
- raise ResolvError.new("DNS result has no information for #{name}")
end
class Requester
@@ -551,6 +825,10 @@ class Resolv
return @string
end
+ def inspect
+ return "#<#{self.class} #{self.to_s}>"
+ end
+
def ==(other)
return @downcase == other.downcase
end
@@ -1101,7 +1379,7 @@ class Resolv
end
def self.decode_rdata(msg)
- preference = msg.get_unpack('n')
+ preference, = msg.get_unpack('n')
exchange = msg.get_name
return self.new(preference, exchange)
end
@@ -1180,7 +1458,7 @@ class Resolv
def self.decode_rdata(msg)
address = IPv4.new(msg.get_bytes(4))
- protocol = msg.get_unpack("n")
+ protocol, = msg.get_unpack("n")
bitmap = msg.get_bytes
return self.new(address, protocol, bitmap)
end
@@ -1239,6 +1517,10 @@ class Resolv
return sprintf("%d.%d.%d.%d", *@address.unpack("CCCC"))
end
+ def inspect
+ return "#<#{self.class} #{self.to_s}>"
+ end
+
def to_name
return DNS::Name.new(
@address.unpack("CCCC").reverse + ['in-addr', 'arpa'])
@@ -1312,7 +1594,7 @@ class Resolv
def initialize(address)
unless address.kind_of?(String) && address.length == 16
- raise ArgumentError.new('IPv4 address muse be 16 bytes')
+ raise ArgumentError.new('IPv6 address muse be 16 bytes')
end
@address = address
end
@@ -1326,6 +1608,10 @@ class Resolv
return address
end
+ def inspect
+ return "#<#{self.class} #{self.to_s}>"
+ end
+
def to_name
return DNS::Name.new(
@address.unpack("H32")[0].split(//).reverse + ['ip6', 'int'])
@@ -1345,5 +1631,5 @@ class Resolv
end
DefaultResolver = self.new
- AddressRegex = /(?:#{IPv4::Regex.source})|(?:#{IPv6::Regex})/
+ AddressRegex = /(?:#{IPv4::Regex.source})|(?:#{IPv6::Regex.source})/
end
diff --git a/parse.y b/parse.y
index 7852163b58..ed18f5e355 100644
--- a/parse.y
+++ b/parse.y
@@ -669,24 +669,29 @@ arg : lhs '=' arg
}
| variable tOP_ASGN {$$ = assignable($1, 0);} arg
{
- if ($2 == tOROP) {
- $<node>3->nd_value = $4;
- $$ = NEW_OP_ASGN_OR(gettable($1), $<node>3);
- if (is_instance_id($1)) {
- $$->nd_aid = $1;
+ if ($<node>3) {
+ if ($2 == tOROP) {
+ $<node>3->nd_value = $4;
+ $$ = NEW_OP_ASGN_OR(gettable($1), $<node>3);
+ if (is_instance_id($1)) {
+ $$->nd_aid = $1;
+ }
}
- }
- else if ($2 == tANDOP) {
- $<node>3->nd_value = $4;
- $$ = NEW_OP_ASGN_AND(gettable($1), $<node>3);
+ else if ($2 == tANDOP) {
+ $<node>3->nd_value = $4;
+ $$ = NEW_OP_ASGN_AND(gettable($1), $<node>3);
+ }
+ else {
+ $$ = $<node>3;
+ if ($$) {
+ $$->nd_value = call_op(gettable($1),$2,1,$4);
+ }
+ }
+ fixpos($$, $4);
}
else {
- $$ = $<node>3;
- if ($$) {
- $$->nd_value = call_op(gettable($1),$2,1,$4);
- }
+ $$ = 0;
}
- fixpos($$, $4);
}
| primary '[' aref_args ']' tOP_ASGN arg
{
diff --git a/string.c b/string.c
index 6695f607c3..8be5e8721d 100644
--- a/string.c
+++ b/string.c
@@ -211,6 +211,8 @@ rb_str_dup(str)
}
else if (RSTRING(str)->orig) {
str2 = rb_str_new3(RSTRING(str)->orig);
+ FL_UNSET(str2, FL_TAINT);
+ OBJ_INFECT(str2, str);
}
else {
str2 = rb_str_new3(rb_str_new4(str));
diff --git a/version.h b/version.h
index dd408f4e7b..c17a86f5fe 100644
--- a/version.h
+++ b/version.h
@@ -1,4 +1,4 @@
#define RUBY_VERSION "1.6.5"
-#define RUBY_RELEASE_DATE "2001-11-01"
+#define RUBY_RELEASE_DATE "2001-11-07"
#define RUBY_VERSION_CODE 165
-#define RUBY_RELEASE_CODE 20011101
+#define RUBY_RELEASE_CODE 20011107