Filenames starting with a dot (and no other dots) are commonly treated
as filenames with no extension rather than an extension. This is also
the behavior mandated in C++17 filesystem.
Reported in https://github.com/boostorg/filesystem/issues/88.
The print name can be empty for some reparse points (e.g. mount points
created by Box cloud storage driver and directory junctions created by
junction.exe). It is supposed to be mostly used for presenting a "simple"
path to the user and not to actually locate the file.
The substitute name is the actionable replacement path, but it is in
NT path format and can potentially point to unmounted volumes and
UNC resources. The implementation attempts to convert the NT path
to Win32 path by matching commonly known patterns against the NT path.
If no pattern matches, we create a Win32 path by converting the NT path
prefix to "\\?\".
Related to https://github.com/boostorg/filesystem/issues/187.
The new implementation is also not relying on the root name format and
is more pertormant as it avoids unnecessarily copying path elements during
operation.
Note that this commit does not remove the trailing dot elements in the
normalized paths.
- Unified root name and root directory parsing that was scattered and
duplicated across different algorithms. The new implementation is
consolidated in a single function for parsing root name and root
directory, which is used from various algorithms.
- The new root name parsing now supports Windows local device ("\\.\")
and NT path ("\??\") prefixes. It also adds support for filesystem
("\\?\") prefix to some of the higher level algorithms that were
using custom parsing previously. Tests updated to verify these prefixes.
- Some of the path decomposition methods were unified with presence checking
methods (e.g. root_name with has_root_name). This makes these methods
work consistently and also makes the has_* methods less expensive as
they no longer have to construct a path only to check if it is empty.
- The filename accessor no longer returns root name if the whole path
only consists of a root name. This also affects stem and extension as
those accessors are based on filename. This is a breaking change.
- Cleaned up code:
- Removed redundant checks for std::wstring support.
- Added header/footer headers to globally disable compiler warnings.
- Removed commented out super-deprecated code.
- Added missing includes and removed includes that are not needed.
- Nonessential code formatting.
When canonical() resolves symlink, it is possible that a symlink resolves
to an absolute path with a different root. We need to update the root
path so that when we restart symlink resolution the check for the
root path still works.
Also, slightly refactored the canonical() implementation to reduce code
size and possibly optimize the generated code.
The buffer size is now selected based on the file size and filesystem block
size and is limited with min and max. This allows to reduce memory consumption
and possibly increase performance when copying smaller files.
Some filesystems have regular files with generated content. Such files have
arbitrary size, including zero, but have actual content. Linux system calls
sendfile or copy_file_range will not copy contents of such files, so we must
use a read/write loop to handle them.
Check the type of the source filesystem before using sendfile or
copy_file_range and fallback to the read/write loop if it matches one of
the blacklisted filesystems: procfs, sysfs, tracefs or debugfs.
Also, added a test to verify that copy_file works on procfs.
Since sendfile and copy_file_range can fail for some filesystems
(e.g. eCryptFS), we have to fallback to the read/write loop in copy_file
implementation. Additionally, since we implement the fallback now,
fallback to sendfile if copy_file_range fails with EXDEV and use
copy_file_range on older kernels that don't implement it for
cross-filesystem copying. This may be beneficial if copy_file_range
is used within a filesystem, and is performed on a remote server NFS or CIFS).
Also, it was discovered that copy_file_range can also fail with EOPNOTSUPP
when it is performed on an NFSv4 filesystem and the remote server does
not support COPY operation. This happens on some patched kernels in RHEL/CentOS.
Lastly, to make sure the copy_file_data pointer is accessed atomically,
it is now declared as an atomic value. If std::atomic is unavailable,
Boost.Atomic is used.
Fixes https://github.com/boostorg/filesystem/issues/184.
These options allow to synchronize the copied data and attributes with
the permanent storage. Note that by default on POSIX systems copy_file
used to synchronize data in previous releases, and this commit changes
this. The caller now has to explicitly request syncing, as it has
significant performance implications.
Closes https://github.com/boostorg/filesystem/issues/186.
At least HP-UX is known to leave the file descriptor open if close() returns
EINTR. On other systems (Linux, BSD, Solaris, AIX) the file descriptor
is closed in the same situation, and closing it again may potentially close
the wrong descriptor if it is reused by another thread. We introduce
close_fd internal helper to abstract away these platform differences.
By defining these new config macros the user can configure the library
to avoid using some system APIs even if they are detected as available
by the library build scripts. This can be useful in case if the API
is known to consistently fail at runtime on the target system.
Related to https://github.com/boostorg/filesystem/issues/172.
create_directories used to ignore errors returned by status()
calls issued internally. The operation would likely fail anyway,
but the error codes returned by create_directories would be incorrect.
Also, it is better to terminate the operation as early as possible
when an error is encountered.
Reported in https://github.com/boostorg/filesystem/issues/182.
The Linux statx system call allows to specify the data the caller is
interested in. This has the potential of improving performance
if some information is expensive to provide.
Also, changed hard_link_count to return static_cast<uintmax_t>(-1)
in case of errors. Changed file_size to report ENOSYS instead of
EPERM when the operation is invoked on a non-regular file.
This follows C++20 definition, which returns a minimum representable time
point value in case of error.
Also, slight refactoring of last_write_time setter function and a fix
to ensure the error code is cleared incase of success.
Auto-linking can still be useful to users of MSVC and compatible
compilers on Windows, when the user links against static build of
Boost.Filesystem. This feature is marked deprecated though, so
it can be removed in the future, when the generated CMake config
files include information about third-party dependencies of Boost
libraries.
Additionally, restored support for linking against Windows CE-cpecific
coredll library. This platform is not tested though and therefore not
properly supported.
Closes https://github.com/boostorg/filesystem/issues/156.
When the source path is not absolute and copy_options::create_symlinks is
specified, deduce the relative path from the target location to the source
file to create a symlink. This allows to copy to a path that is not the current
path.
Also, added absolute overloads taking error_code argyment.
Also, when current_path() is used as a default argument to other operations,
and the operation also accepts error_code, use current_path(ec) to report
errors through the error code rather than throwing an exception.
Also, added a test for copy operation.
The updated copy implementation follows C++20 [fs.op.copy] definition
and implements additional copy options.
The new create_directory overloads accepting two paths are functionally
similar to copy_directory, but are compliant with C++20
[fs.op.create.directory]. The copy_directory operation has been deprecated
in favor of create_directory.
The copy_file operation implementation has been inlined into the
detail::copy_file function. The part that copies the file body has been
extracted to a separate function, so that addition of specialized copy
implementations later is possible.
Added copy_options enum, which reflects the enum from C++20. Currently,
only overwrite_existing option is supported. Other options will be added
later.
The old enum copy_option is deprecated in favor of copy_options.
Updated docs to reflect recent changes to copy_file behavior.
space() now initializes space_info members to -1 values, which is used when the
structure is returned in case of error.
On Windows, check if the path refers to a directory, and use the parent
directory if not. In order to make sure we return space information for the
target filesystem, we have to resolve symlinks in this case.
Fixes https://github.com/boostorg/filesystem/issues/73.
This ensures that the files overwritten or created by copy_file have the same
permission bits as the source file, as required by C++20. Also, for the duration
of the copy operation we ensure the target file has writing permission set.
This is important e.g. for NFS, which checks the permission on the server,
so a writable file descriptor on the client is not enough for the write
operation to succeed.
Notably, this doesn't save the case of overwriting the file with no write
permission set. In this case the operation will fail with EPERM.
Also, use fsync/fdatasync to guarantee that the target file is written
completely without errors before closing the file descriptor.
The POSIX copy_file implementation has beed reworked to perform checks for
whether the source and target files are regilar files and whether the source
and target paths identify the same file. Also, the implementation has been fixed
to report the correct error code from the failed operation to the caller
in case of failure. The implementation is now also protected against EINTR
errors and uses O_CLOEXEC when possible to avoid leaking file descriptors
if the caller process forks.
Also, the file equivalence test is now simplified to not test the file size
and last modification time. These tests had a potential of causing a false
negative, if the file that is being tested was modified between the stat()
calls that were used to obtain file information from the paths.
Closes https://github.com/boostorg/filesystem/pull/48.
The algorithm implementation now ignores empty and dot path elements in the
argument path and accounts dot-dot elements by decreasing the number of
dot-dot elements to generate in the resulting relative path. This is
according to C++17 std::path specification [fs.path.gen]/4.
Fixes https://github.com/boostorg/filesystem/issues/76.
The new option allows to skip dangling directory symlinks when iterating
over a directory using recursive_directory_iterator.
This also updates the operations_test, which failed spuriously because
the test created dangling symlinks for some of its checks. Since the order
of iteration is undefined, the tests sometimes passed, when the dangling
symlinks were encountered late during the iteration.
The directory_options enum reflects the same-named enum from C++20. It is now
supported by both directory_iterator and recursive_directory_iterator. In
particular, both iterators now support skip_permission_denied option.
recursive_directory_iterator is now set to end by default on errors, as
required by C++20. An additional directory_options::pop_on_error policy
is added to allow the iterator recover from an error. When this option is
specified and an error occurs, the iterator repeatedly pops the recursion level
until the pop completes successfully or the end state is reached.
recursive_directory_iterator that have standard counterparts (level,
no_push_pending, no_push_request and no_push) are now deprecated and can be
removed by defining BOOST_FILESYSTEM_NO_DEPRECATED. These members will be
removed in a future release.
Docs and tests updated accordingly. Also, in docs reconstructed release history
for the past releases from Boost release notes.
Fixes https://github.com/boostorg/filesystem/issues/112
Fixes https://github.com/boostorg/filesystem/issues/113