diff --git a/lib/fileutils.rb b/lib/fileutils.rb index 8ae5266864..4ba7d18a5d 100644 --- a/lib/fileutils.rb +++ b/lib/fileutils.rb @@ -2328,13 +2328,21 @@ module FileUtils def postorder_traverse if directory? - entries().each do |ent| + begin + children = entries() + rescue Errno::EACCES + # Failed to get the list of children. + # Assuming there is no children, try to process the parent directory. + yield self + return + end + + children.each do |ent| ent.postorder_traverse do |e| yield e end end end - ensure yield self end diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb index 8c49eb39bb..05ba8d184a 100644 --- a/test/fileutils/test_fileutils.rb +++ b/test/fileutils/test_fileutils.rb @@ -750,6 +750,24 @@ class TestFileUtils < Test::Unit::TestCase assert_file_not_exist 'tmp/tmpdir3' end + def test_rm_r_no_permissions + check_singleton :rm_rf + + return if /mswin|mingw/ =~ RUBY_PLATFORM + + mkdir 'tmpdatadir' + touch 'tmpdatadir/tmpdata' + chmod "-x", 'tmpdatadir' + + begin + assert_raise Errno::EACCES do + rm_r 'tmpdatadir' + end + ensure + chmod "+x", 'tmpdatadir' + end + end + def test_remove_entry_cjk_path dir = "tmpdir\u3042" my_rm_rf dir