Skip to content

Commit

Permalink
[ruby/fileutils] Make mkdir_p only attempt to create necessary direct…
Browse files Browse the repository at this point in the history
…ories

Previously, if creating the directory directly didn't work
and the directory didn't exist, mkdir_p would create all
directories from the root.  This modifies the approach to
check whether the directory exists when walking up the
directory tree from the argument, and once you have found an
intermediate directory that exists, you only need to create
directories under it.

This approach has a couple advantages:

1) It performs better when most directories in path already exist,
and that will be true for most usage of mkdir_p, as mkdir_p is
usually called with paths where the first few directories exist
and only the last directory or last few directories do not.

2) It works in file-system access limited environments such as
when unveil(2) is used on OpenBSD.  In these environments, if
/foo/bar/baz exists and is unveiled, you can do
`mkdir /foo/bar/baz/xyz` but `mkdir /foo` and `mkdir /foo/bar` raise
Errno::ENOENT.

ruby/fileutils@ec0c229e78
  • Loading branch information
jeremyevans authored and hsbt committed Dec 4, 2020
1 parent e666bd1 commit da12625
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/fileutils.rb
Expand Up @@ -223,8 +223,9 @@ def mkdir_p(list, mode: nil, noop: nil, verbose: nil)
until path == stack.last # dirname("/")=="/", dirname("C:/")=="C:/"
stack.push path
path = File.dirname(path)
break if File.directory?(path)
end
stack.pop # root directory should exist
stack.pop if path == stack.last # root directory should exist
stack.reverse_each do |dir|
begin
fu_mkdir dir, mode
Expand Down

0 comments on commit da12625

Please sign in to comment.