From aaaf4f8d4bc6db1ee12f9f4f1a21b4fbbcfdebf5 Mon Sep 17 00:00:00 2001
From: hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Wed, 7 Nov 2018 15:55:14 +0000
Subject: [PATCH 01/11] Dir.children is available since Feature #11302.
 FileUtils uses Dir.each on an internal method encapsulated on a private class
 `Entry_#entry`, having no '.' neither '..' entries would make now superfluous
 a chained reject filtering.

This change can improve the performance of these FileUtils
methods when the provided path covers thousands of files or
directories:

- chmod_R
- chown_R
- remove_entry
- remove_entry_secure
- rm_r
- remove_dir
- copy_entry

Related: Feature #13896 https://bugs.ruby-lang.org/issues/13896

[Feature #14109][Fix GH-1754]

Co-Authored-By: esparta <esparta@gmail.com>

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65610 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 lib/fileutils.rb | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index 7cbc6f4..d7b2429 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -1274,8 +1274,7 @@ def door?
     def entries
       opts = {}
       opts[:encoding] = ::Encoding::UTF_8 if fu_windows?
-      Dir.entries(path(), opts)\
-          .reject {|n| n == '.' or n == '..' }\
+      Dir.children(path, opts)\
           .map {|n| Entry_.new(prefix(), join(rel(), n.untaint)) }
     end
 

From 01860be08eacb6096203f4273b856e949a7612c3 Mon Sep 17 00:00:00 2001
From: naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Wed, 6 Mar 2019 07:14:13 +0000
Subject: [PATCH 02/11] merge revision(s) 66972: [Backport #15577]

	Fix exception namespace

	* lib/fileutils.rb (remove_entry_secure): EISDIR is under the
	  Errno namespace.  [ruby-core:91362] [Bug #15577]

	From: Tietew (Toru Iwase) <tietew@tietew.net>

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67177 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 lib/fileutils.rb                 | 2 +-
 test/fileutils/test_fileutils.rb | 8 ++++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index d7b2429..8cd38c3 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -698,7 +698,7 @@ def remove_entry_secure(path, force = false)
         f.chown euid, -1
         f.chmod 0700
       }
-    rescue EISDIR # JRuby in non-native mode can't open files as dirs
+    rescue Errno::EISDIR # JRuby in non-native mode can't open files as dirs
       File.lstat(dot_file).tap {|fstat|
         unless fu_stat_identical_entry?(st, fstat)
           # symlink (TOC-to-TOU attack?)
diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb
index f260000..64dd246 100644
--- a/test/fileutils/test_fileutils.rb
+++ b/test/fileutils/test_fileutils.rb
@@ -740,7 +740,15 @@ def test_remove_entry_secure
     remove_entry_secure 'tmp/tmpdir/c', true
     assert_file_not_exist 'tmp/tmpdir/a'
     assert_file_not_exist 'tmp/tmpdir/c'
+
+    File.chmod(01777, 'tmp/tmpdir')
+    Dir.mkdir 'tmp/tmpdir/d', 0
+    assert_raise(Errno::EACCES) {remove_entry_secure 'tmp/tmpdir/d'}
+    File.chmod 0777, 'tmp/tmpdir/d'
+    Dir.rmdir 'tmp/tmpdir/d'
+
     Dir.rmdir 'tmp/tmpdir'
+
   end
 
   def test_remove_entry_secure_symlink

From 8adc41f4632cda5ae01f1cd22f0800345d4f6a6a Mon Sep 17 00:00:00 2001
From: naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Mon, 11 Mar 2019 07:18:45 +0000
Subject: [PATCH 03/11] merge revision(s) 66973: [Backport #15577]

	Run r66972 assertion only when a sticky-bit makes sense

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67210 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 test/fileutils/test_fileutils.rb | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb
index 64dd246..f74ae5a 100644
--- a/test/fileutils/test_fileutils.rb
+++ b/test/fileutils/test_fileutils.rb
@@ -742,13 +742,14 @@ def test_remove_entry_secure
     assert_file_not_exist 'tmp/tmpdir/c'
 
     File.chmod(01777, 'tmp/tmpdir')
-    Dir.mkdir 'tmp/tmpdir/d', 0
-    assert_raise(Errno::EACCES) {remove_entry_secure 'tmp/tmpdir/d'}
-    File.chmod 0777, 'tmp/tmpdir/d'
-    Dir.rmdir 'tmp/tmpdir/d'
+    if File.sticky?('tmp/tmpdir')
+      Dir.mkdir 'tmp/tmpdir/d', 0
+      assert_raise(Errno::EACCES) {remove_entry_secure 'tmp/tmpdir/d'}
+      File.chmod 0777, 'tmp/tmpdir/d'
+      Dir.rmdir 'tmp/tmpdir/d'
+    end
 
     Dir.rmdir 'tmp/tmpdir'
-
   end
 
   def test_remove_entry_secure_symlink

From ec46a551724be5a522d336bf173aa7a459b9b9c6 Mon Sep 17 00:00:00 2001
From: naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Thu, 28 Mar 2019 03:24:57 +0000
Subject: [PATCH 04/11] merge revision(s) 67247: [Backport #15666]

	Guard out the test when it is run under root permission

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67351 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 test/fileutils/test_fileutils.rb | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb
index f74ae5a..c81f5b4 100644
--- a/test/fileutils/test_fileutils.rb
+++ b/test/fileutils/test_fileutils.rb
@@ -741,12 +741,14 @@ def test_remove_entry_secure
     assert_file_not_exist 'tmp/tmpdir/a'
     assert_file_not_exist 'tmp/tmpdir/c'
 
-    File.chmod(01777, 'tmp/tmpdir')
-    if File.sticky?('tmp/tmpdir')
-      Dir.mkdir 'tmp/tmpdir/d', 0
-      assert_raise(Errno::EACCES) {remove_entry_secure 'tmp/tmpdir/d'}
-      File.chmod 0777, 'tmp/tmpdir/d'
-      Dir.rmdir 'tmp/tmpdir/d'
+    unless root_in_posix?
+      File.chmod(01777, 'tmp/tmpdir')
+      if File.sticky?('tmp/tmpdir')
+        Dir.mkdir 'tmp/tmpdir/d', 0
+        assert_raise(Errno::EACCES) {remove_entry_secure 'tmp/tmpdir/d'}
+        File.chmod 0777, 'tmp/tmpdir/d'
+        Dir.rmdir 'tmp/tmpdir/d'
+      end
     end
 
     Dir.rmdir 'tmp/tmpdir'

From 86846ce336ce896798a4d944f9ab4fafceca92b6 Mon Sep 17 00:00:00 2001
From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Tue, 2 Mar 2021 11:23:42 +0000
Subject: [PATCH 05/11] merge revision(s) a19228f8: [Backport #16979]

	brace the fact that lchmod(2) can EOPNOTSUPP

	Musl libc has this function as a tiny wrapper of fchmodat(3posix).  On
	the other hand Linux kernel does not support changing modes of a symlink.
	The operation always fails with EOPNOTSUPP.  This fchmodat behaviour is
	defined in POSIX.  We have to take care of such exceptions.
	---
	 lib/fileutils.rb               |  3 ++-
	 test/pathname/test_pathname.rb |  2 +-
	 test/ruby/test_notimp.rb       | 19 ++++++++++++-------
	 3 files changed, 15 insertions(+), 9 deletions(-)

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67907 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 lib/fileutils.rb | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index 8cd38c3..0ec9e0d 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -1320,6 +1320,7 @@ def chmod(mode)
       else
         File.chmod mode, path()
       end
+    rescue Errno::EOPNOTSUPP
     end
 
     def chown(uid, gid)
@@ -1411,7 +1412,7 @@ def copy_metadata(path)
       if st.symlink?
         begin
           File.lchmod mode, path
-        rescue NotImplementedError
+        rescue NotImplementedError, Errno::EOPNOTSUPP
         end
       else
         File.chmod mode, path

From da8aa3140559b1af3fb4b7adbe88452fd0ea00ea Mon Sep 17 00:00:00 2001
From: hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Tue, 15 May 2018 05:53:18 +0000
Subject: [PATCH 06/11] Retry to merge fileutils-1.1.0.

  * Revert "Revert "Merge fileutils-1.1.0.""
    This reverts commit 84bb8e81c25d4d7d6020c3acfbbc36e9064200fa.

  * Added workaround for make mjit-headers

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63430 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 lib/fileutils.rb | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index 0ec9e0d..016c78c 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -85,7 +85,11 @@
 # <tt>:verbose</tt> flags to methods in FileUtils.
 #
 
-require 'rbconfig'
+begin
+  require 'rbconfig'
+rescue LoadError
+  # for make mjit-headers
+end
 
 module FileUtils
 

From 4d656b5f45e4de56dd842bf9e78479ffac3453a0 Mon Sep 17 00:00:00 2001
From: stomar <stomar@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Wed, 3 Oct 2018 19:19:33 +0000
Subject: [PATCH 07/11] fileutils.rb: restore documentation for FileUtils

* lib/fileutils.rb: [DOC] restore documentation for FileUtils module
  which became undocumented with r63430.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64911 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 lib/fileutils.rb | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index 016c78c..aa6472d 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -1,5 +1,11 @@
 # frozen_string_literal: true
-#
+
+begin
+  require 'rbconfig'
+rescue LoadError
+  # for make mjit-headers
+end
+
 # = fileutils.rb
 #
 # Copyright (c) 2000-2007 Minero Aoki
@@ -83,13 +89,6 @@
 # This module has all methods of FileUtils module, but never changes
 # files/directories.  This equates to passing the <tt>:noop</tt> and
 # <tt>:verbose</tt> flags to methods in FileUtils.
-#
-
-begin
-  require 'rbconfig'
-rescue LoadError
-  # for make mjit-headers
-end
 
 module FileUtils
 

From 0af35ddd9a222fc617395456b4bb110596a61aa6 Mon Sep 17 00:00:00 2001
From: hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Sat, 20 Oct 2018 07:03:55 +0000
Subject: [PATCH 08/11] Merge fileutils from ruby/fileutils on GitHub.

  * It was separated version file for gemspec.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65207 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 fileutils.gemspec        | 11 +++++++++--
 lib/fileutils.rb         |  9 +++++----
 lib/fileutils/version.rb |  5 +++++
 3 files changed, 19 insertions(+), 6 deletions(-)
 create mode 100644 lib/fileutils/version.rb

diff --git a/fileutils.gemspec b/fileutils.gemspec
index a72b878..7212883 100644
--- a/fileutils.gemspec
+++ b/fileutils.gemspec
@@ -1,13 +1,20 @@
 # frozen_string_literal: true
 
+begin
+  require_relative "lib/fileutils/version"
+rescue LoadError
+  # for Ruby core repository
+  require_relative "version"
+end
+
 Gem::Specification.new do |s|
   s.name = "fileutils"
-  s.version = '1.1.0'
+  s.version = FileUtils::VERSION
   s.summary = "Several file utility methods for copying, moving, removing, etc."
   s.description = "Several file utility methods for copying, moving, removing, etc."
 
   s.require_path = %w{lib}
-  s.files = [".gitignore", ".travis.yml", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "fileutils.gemspec", "lib/fileutils.rb"]
+  s.files = [".gitignore", ".travis.yml", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "fileutils.gemspec", "lib/fileutils.rb", "lib/fileutils/version.rb"]
   s.required_ruby_version = ">= 2.3.0"
 
   s.authors = ["Minero Aoki"]
diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index aa6472d..40a8e6a 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -6,6 +6,9 @@
   # for make mjit-headers
 end
 
+require "fileutils/version"
+
+#
 # = fileutils.rb
 #
 # Copyright (c) 2000-2007 Minero Aoki
@@ -62,7 +65,7 @@
 #
 # There are some `low level' methods, which do not accept any option:
 #
-#   FileUtils.copy_entry(src, dest, preserve = false, dereference = false)
+#   FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
 #   FileUtils.copy_file(src, dest, preserve = false, dereference = true)
 #   FileUtils.copy_stream(srcstream, deststream)
 #   FileUtils.remove_entry(path, force = false)
@@ -89,11 +92,9 @@
 # This module has all methods of FileUtils module, but never changes
 # files/directories.  This equates to passing the <tt>:noop</tt> and
 # <tt>:verbose</tt> flags to methods in FileUtils.
-
+#
 module FileUtils
 
-  VERSION = "1.1.0"
-
   def self.private_module_function(name)   #:nodoc:
     module_function name
     private_class_method name
diff --git a/lib/fileutils/version.rb b/lib/fileutils/version.rb
new file mode 100644
index 0000000..e82734d
--- /dev/null
+++ b/lib/fileutils/version.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+module FileUtils
+  VERSION = "1.1.0"
+end

From b4a92a8a410a09b0ba7e96eae3763120b5d80765 Mon Sep 17 00:00:00 2001
From: hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Tue, 15 May 2018 10:10:33 +0000
Subject: [PATCH 09/11] Added workaround to fileutils for `make btest` without
 rbconfig.

  Followed up r63430.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63434 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 lib/fileutils.rb | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index 40a8e6a..4c27d4b 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -548,7 +548,11 @@ def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
   module_function :move
 
   def rename_cannot_overwrite_file?   #:nodoc:
-    /emx/ =~ RbConfig::CONFIG['host_os']
+    if defined?(RbConfig)
+      /emx/ =~ RbConfig::CONFIG['host_os']
+    else
+      /emx/ =~ RUBY_PLATFORM
+    end
   end
   private_module_function :rename_cannot_overwrite_file?
 
@@ -1153,7 +1157,11 @@ module StreamUtils_
     private
 
     def fu_windows?
-      /mswin|mingw|bccwin|emx/ =~ RbConfig::CONFIG['host_os']
+      if defined?(RbConfig)
+        /mswin|mingw|bccwin|emx/ =~ RbConfig::CONFIG['host_os']
+      else
+        /mswin|mingw|bccwin|emx/ =~ RUBY_PLATFORM
+      end
     end
 
     def fu_copy_stream0(src, dest, blksize = nil)   #:nodoc:

From 6136d96dc7b3a70e29246e5654f2a25dbf135f1c Mon Sep 17 00:00:00 2001
From: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Wed, 16 May 2018 01:31:28 +0000
Subject: [PATCH 10/11] fileutils.rb: remove code for OS/2 emx

* lib/fileutils.rb (FileUtils#mv): remove code for OS/2 emx, its
  support has been dropped yeas ago.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63440 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 lib/fileutils.rb | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index 4c27d4b..1219e31 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -523,8 +523,6 @@ def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
         if destent.exist?
           if destent.directory?
             raise Errno::EEXIST, d
-          else
-            destent.remove_file if rename_cannot_overwrite_file?
           end
         end
         begin
@@ -547,15 +545,6 @@ def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
   alias move mv
   module_function :move
 
-  def rename_cannot_overwrite_file?   #:nodoc:
-    if defined?(RbConfig)
-      /emx/ =~ RbConfig::CONFIG['host_os']
-    else
-      /emx/ =~ RUBY_PLATFORM
-    end
-  end
-  private_module_function :rename_cannot_overwrite_file?
-
   #
   # Remove file(s) specified in +list+.  This method cannot remove directories.
   # All StandardErrors are ignored when the :force option is set.

From 5f50ab305e43ea5ebff85e8edeeb02e28488e78d Mon Sep 17 00:00:00 2001
From: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Sat, 19 May 2018 00:22:39 +0000
Subject: [PATCH 11/11] fileutils.rb: split fu_windows?

* lib/fileutils.rb (FileUtils::StreamUtils_#fu_windows?): select
  the method definition for each platforms, and dropped supports
  for deprecated platforms.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63465 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 lib/fileutils.rb | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index 1219e31..6332fcd 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -1145,12 +1145,11 @@ def touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil)
   module StreamUtils_
     private
 
-    def fu_windows?
-      if defined?(RbConfig)
-        /mswin|mingw|bccwin|emx/ =~ RbConfig::CONFIG['host_os']
-      else
-        /mswin|mingw|bccwin|emx/ =~ RUBY_PLATFORM
-      end
+    case (defined?(::RbConfig) ? ::RbConfig::CONFIG['host_os'] : ::RUBY_PLATFORM)
+    when /mswin|mingw/
+      def fu_windows?; true end
+    else
+      def fu_windows?; false end
     end
 
     def fu_copy_stream0(src, dest, blksize = nil)   #:nodoc:
