From aaaf4f8d4bc6db1ee12f9f4f1a21b4fbbcfdebf5 Mon Sep 17 00:00:00 2001 From: hsbt 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 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 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) 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 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 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 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 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 @@ # :verbose 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 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 :noop and # :verbose 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 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 :noop and # :verbose 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 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 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 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: