Turns out, suppressing -Wsign-compare doesn't work on gcc 8 in MinGW-w64
at least in one instance. So we have to do it the hard way and explicitly
cast NTSTATUS values on every comparison.
STATUS_* constants defined in ntstatus.h are defined as DWORDs, and NTSTATUS
is long. This results in signed/unsigned mismatch warnings emitted by gcc and
clang. Consider that a platform bug and disable the warning.
Closes https://github.com/boostorg/filesystem/issues/321.
When weakly_canonical was called with a relative input path, the operation
would test path elements for existence, which meant resolving them relative
to the current path instead of the base path specified in the call. To
mitigate this, make the source path absolute using the specified base path.
As a side effect, this fixes incorrect path produced on Windows if the
input path started with "..". The algorithm was unable to remove the last
element of the head path because there was none. As a result, the remaining
elements of the input path were appended to the full base path by canonical.
Fixes to https://github.com/boostorg/filesystem/issues/311.
copy_file_tests with copy_options::update_existing used to fail sometimes,
when the last modification timestamps on the test files were close enough.
Run the tests after a pause to make sure the timestamps are far enough apart.
This makes directory_entry::status, directory_entry::symlink_status, as well
as related methods behave similarly to the equivalent standalone operations.
std::filesystem specification for directory_entry::refresh doesn't explicitly
say that the file not existing is not an error, but it does say that
directory_entry::status and directory_entry::symlink_status should behave
the same way as the standalone operations. Currently, libstdc++, libc++
and MSVC standard library all avoid throwing the exception from
directory_entry::refresh if the file doesn't exist.
Closes https://github.com/boostorg/filesystem/issues/314.
GetFileAttributesExW that was used to implement file_size and is_empty
on Windows returns information about the symlink rather than the file
the symlink refers to. Fix this by opening the file and using
GetFileInformationByHandle to obtain the file size and attributes.
Additionally, reworked is_empty implementation to reuse the file handle
(and fd on POSIX systems) to create the directory iterator if the
operation is invoked on a directory. On POSIX systems, implement a
more lightweight version of is_empty_directory when readdir is safe
to use. Reusing the file handle/fd improves protection against
filesystem races, when the file that is being tested by is_empty
is initially a directory and then, when we create a directory
iterator, it is not.
Fixes https://github.com/boostorg/filesystem/issues/313.
Instead of passing a base directory fd, pass the directory fd to iterate over.
This simplifies code a little and makes it closer to Windows version.
Also, use unique_fd from Boost.Scope instead of a custom fd wrapper. Also
added handling of EINTR returned from open/openat in more places.
This partly restores documentation removed in
5df060e95c and moves the features from
"deprecated" table to a new "removed" table. This provides users
with suggested replacements for the removed features.
Since we now require C++11 scoped enums and removed deprecated enums,
we can now pass copy_options and directory_options to the compiled
library without converting to the underlying type.
Removed APIs that were marked as deprecated a long time ago. Disabled
by default support for path construction, assignment and appending from
container types. Users can still enable this functionality by defining
BOOST_FILESYSTEM_DEPRECATED.
Updated docs, tests and examples accordingly.
Use nullptr, rvalue references, default function template parameters,
deleted/defaulted functions, noexcept, final, override and scoped enums.
Don't use constexpr yet, as it would raise MSVC requirement.
This follows the absolute() definition in the docs, as in v4 appending
an empty path results in a trailing slash.
Unfortunately, this also influences canonical and weakly_canonical,
so we had to duplicate those for v3 and v4 as well.
Fixes https://github.com/boostorg/filesystem/issues/301.
In v3, equivaluent would successfully return false if one of the paths
existed and the other one didn't. v4 now fails in this case, similar
to std::filesystem.
This reflects the actual implementation and effectively allows
canonical("") to work, which is essential for weakly_canonical("a/b"),
where "a" doesn't exist, to succeed.
Related to https://github.com/boostorg/filesystem/issues/300.
Use Linux fallocate system call to preallocate storage for the target
file in copy_file backends based on sendfile and copy_file_range. These
backends are only used when the file size is known beforehand, and
preallocating storage allows to reduce filesystem fragmentation and
get an early error if there's not enough free space on the target
filesystem.
Preallocation is only done as an optimization/hint. On filesystems
that do not support it we continue the data copying process as before.
This is why we aren't using posix_fallocate, because glibc contains
an emulation path that is used when the filesystem doesn't support
the functionality. We don't want this emulation, as it would effectively
double the amount of written data.
If the input path is relative and none of its elements exist in the filesystem,
the head path calculated in weakly_canonical is empty. In this case, we still
need to call canonical on it to produce an absolute path (which will be
equivalent to the base path) and append the tail path to it.
Fixes https://github.com/boostorg/filesystem/issues/300.