summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-10-13 19:46:07 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-10-13 19:46:07 +0000
commit839ef7bfbb446db531983e391a52df4e4a0eb8aa (patch)
treedf973e2532aefcd7649784a2c9ef1c113ac1a305
parent345f1ac53dc4e7bdbeb0bdc4994110109c524773 (diff)
* lib/pathname.rb (realpath): make ELOOP check bit more robust.
(children): prepend self by default. (chroot): obsoleted. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4757 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--lib/pathname.rb48
2 files changed, 45 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index f8f94e8..ad21f14 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Tue Oct 14 04:43:55 2003 Tanaka Akira <akr@m17n.org>
+
+ * lib/pathname.rb (realpath): make ELOOP check bit more robust.
+ (children): prepend self by default.
+ (chroot): obsoleted.
+
Tue Oct 14 02:29:31 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (rb_require_safe): segfault after loading .so.
diff --git a/lib/pathname.rb b/lib/pathname.rb
index 8df4915..d104be6 100644
--- a/lib/pathname.rb
+++ b/lib/pathname.rb
@@ -111,11 +111,20 @@ class Pathname
# it may return relative pathname.
# Otherwise it returns absolute pathname.
def realpath(force_absolute=true)
+ # Check file existence at first by File.stat.
+ # This test detects ELOOP.
+ #
+ # /tmp/a -> a
+ # /tmp/b -> b/b
+ # /tmp/c -> ./c
+ # /tmp/d -> ../tmp/d
+
File.stat(@path)
top = %r{\A/} =~ @path ? '/' : ''
unresolved = @path.scan(%r{[^/]+})
resolved = []
+ checked_path = {}
until unresolved.empty?
case unresolved.last
@@ -125,7 +134,9 @@ class Pathname
resolved.unshift unresolved.pop
else
path = top + unresolved.join('/')
- if FileTest.symlink? path
+ raise Errno::ELOOP.new(path) if checked_path[path]
+ checked_path[path] = true
+ if File.lstat(path).symlink?
link = File.readlink(path)
if %r{\A/} =~ link
top = '/'
@@ -211,14 +222,27 @@ class Pathname
end
# Pathname#children returns the children of the directory as an array of
- # pathnames. I.e. it is similar to Pathname#entries except '.' and '..'
- # is not returned.
+ # pathnames.
+ #
+ # By default, self is prepended to each pathname in the result.
+ # It is disabled if false is given for the optional argument
+ # prepend_directory.
+ #
+ # Note that the result never contain '.' and '..' because they are not
+ # child.
#
# This method is exist since 1.8.1.
- def children
- Dir.entries(@path).map {|f|
- f == '.' || f == '..' ? nil : Pathname.new(f)
- }.compact
+ def children(prepend_directory=true)
+ result = []
+ Dir.foreach(@path) {|e|
+ next if e == '.' || e == '..'
+ if prepend_directory
+ result << Pathname.new(File.join(@path, e))
+ else
+ result << Pathname.new(e)
+ end
+ }
+ result
end
# Pathname#relative_path_from returns a relative path from the argument to
@@ -355,14 +379,20 @@ class Pathname
def Pathname.getwd() Pathname.new(Dir.getwd) end
class << self; alias pwd getwd end
- # This method is obsoleted at 1.8.1.
+ # Pathname#chdir is obsoleted at 1.8.1.
#
def chdir(&block) # compatibility to 1.8.0.
warn "Pathname#chdir is obsoleted. Use Dir.chdir."
Dir.chdir(@path, &block)
end
- def chroot() Dir.chroot(@path) end
+ # Pathname#chroot is obsoleted at 1.8.1.
+ #
+ def chroot # compatibility to 1.8.0.
+ warn "Pathname#chroot is obsoleted. Use Dir.chroot."
+ Dir.chroot(@path)
+ end
+
def rmdir() Dir.rmdir(@path) end
def entries() Dir.entries(@path).map {|f| Pathname.new(f) } end