Use realpath(3) instead of custom realpath implementation if available
This approach is simpler than the previous approach which tries to
emulate realpath(3). It also performs much better on both Linux and
OpenBSD on the included benchmarks.
By using realpath(3), we can better integrate with system security
features such as OpenBSD's unveil(2) system call.
This does not use realpath(3) on Windows even if it exists, as the
approach for checking for absolute paths does not work for drive
letters. This can be fixed without too much difficultly, though until
Windows defines realpath(3), there is no need to do so.
For File.realdirpath, where the last element of the path is not
required to exist, fallback to the previous approach, as realpath(3)
on most operating systems requires the whole path be valid (per POSIX),
and the operating systems where this isn't true either plan to conform
to POSIX or may change to conform to POSIX in the future.
glibc realpath(3) does not handle /path/to/file.rb/../other_file.rb
paths, returning ENOTDIR in that case. Fallback to the previous code
if realpath(3) returns ENOTDIR.
glibc doesn't like realpath(3) usage for paths like /dev/fd/5,
returning ENOENT even though the path may appear to exist in the
filesystem. If ENOENT is returned and the path exists, then fall
back to the default approach.
2019-04-28 06:18:55 +03:00
|
|
|
prelude: |
|
|
|
|
f = File
|
|
|
|
pwd = Dir.pwd
|
|
|
|
Dir.mkdir('b') unless f.directory?('b')
|
|
|
|
f.write('b/a', '') unless f.file?('b/a')
|
|
|
|
|
|
|
|
relative = 'b/a'
|
|
|
|
absolute = File.join(pwd, relative)
|
|
|
|
dir = 'b'
|
|
|
|
file = 'a'
|
|
|
|
|
|
|
|
relative_dir = 'b/c'
|
|
|
|
absolute_dir = File.join(pwd, relative_dir)
|
|
|
|
file_dir = 'c'
|
2024-02-09 04:07:15 +03:00
|
|
|
teardown: |
|
|
|
|
require 'fileutils'
|
|
|
|
FileUtils.rm_rf('b')
|
Use realpath(3) instead of custom realpath implementation if available
This approach is simpler than the previous approach which tries to
emulate realpath(3). It also performs much better on both Linux and
OpenBSD on the included benchmarks.
By using realpath(3), we can better integrate with system security
features such as OpenBSD's unveil(2) system call.
This does not use realpath(3) on Windows even if it exists, as the
approach for checking for absolute paths does not work for drive
letters. This can be fixed without too much difficultly, though until
Windows defines realpath(3), there is no need to do so.
For File.realdirpath, where the last element of the path is not
required to exist, fallback to the previous approach, as realpath(3)
on most operating systems requires the whole path be valid (per POSIX),
and the operating systems where this isn't true either plan to conform
to POSIX or may change to conform to POSIX in the future.
glibc realpath(3) does not handle /path/to/file.rb/../other_file.rb
paths, returning ENOTDIR in that case. Fallback to the previous code
if realpath(3) returns ENOTDIR.
glibc doesn't like realpath(3) usage for paths like /dev/fd/5,
returning ENOENT even though the path may appear to exist in the
filesystem. If ENOENT is returned and the path exists, then fall
back to the default approach.
2019-04-28 06:18:55 +03:00
|
|
|
benchmark:
|
|
|
|
relative_nil: "f.realpath(relative, nil)"
|
|
|
|
absolute_nil: "f.realpath(absolute, nil)"
|
|
|
|
relative_relative: "f.realpath(file, dir)"
|
|
|
|
absolute_relative: "f.realpath(absolute, dir)"
|
|
|
|
relative_absolute: "f.realpath(relative, pwd)"
|
|
|
|
relative_nil_dir: "f.realdirpath(relative_dir, nil)"
|
|
|
|
absolute_nil_dir: "f.realdirpath(absolute_dir, nil)"
|
|
|
|
relative_relative_dir: "f.realdirpath(file_dir, dir)"
|
|
|
|
absolute_relative_dir: "f.realdirpath(absolute_dir, dir)"
|
|
|
|
relative_absolute_dir: "f.realdirpath(relative_dir, pwd)"
|
|
|
|
relative_nil_notexist: "f.realpath(relative_dir, nil) rescue nil"
|
|
|
|
absolute_nil_notexist: "f.realpath(absolute_dir, nil) rescue nil"
|
|
|
|
relative_relative_notexist: "f.realpath(file_dir, dir) rescue nil"
|
|
|
|
absolute_relative_notexist: "f.realpath(absolute_dir, dir) rescue nil"
|
|
|
|
relative_absolute_notexist: "f.realpath(relative_dir, pwd) rescue nil"
|