Deduplicated files are reparse points with IO_REPARSE_TAG_DEDUP tag. Such
files are created by a dedup service running in the background, so a regular
file may be converted to a dedup reparse point at any time and without user's
intervention. For all intents and purposes dedup files should look like
normal, regular files, so it makes sense to report them as such in
Boost.Filesystem methods like status(), symlink_status() and everything
based on those. This commit implements this.
Closes https://github.com/boostorg/filesystem/issues/262.
As with directory iterator, ERROR_CALL_NOT_IMPLEMENTED may be returned
by SetFileInformationByHandle in Wine if it doesn't support a certain
information class. Downgrade to an older info class in this case.
This eliminates spinning while iterating over directory contents as by default
file handles created by NtCreateFile are non-blocking. Because of this
NtQueryDirectoryFile didn't block and returned STATUS_PENDING without actually
updating the iteration state. Eventually this would cause directory iteration
to fail with a hard error.
Added ERROR_CALL_NOT_IMPLEMENTED to the list of error codes that are used
to permanently downgrade directory querying method. This error code is
returned by Wine, which up until version 7.21 did not support
FileIdExtdDirectoryRestartInfo and FileFullDirectoryRestartInfo.
Further, use non-permanent downgrade on ERROR_INVALID_PARAMETER. Apparently,
some mounted filesystems don't implement even the older info classes,
such as FileFullDirectoryRestartInfo and FileIdBothDirectoryRestartInfo.
These info classes are otherwise supported by the system and work on other
filesystems.
Lastly, if querying FileIdBothDirectoryRestartInfo fails, fall back to
NtQueryDirectoryFile API.
Fixes https://github.com/boostorg/filesystem/issues/255.
Fixes https://github.com/boostorg/filesystem/issues/266.
Closes https://github.com/boostorg/filesystem/pull/267.
As the compiler considers filesystem::create_directory overload that takes
path as the second argument, if NULL is defined as nullptr the compiler
attempts to construct path from nullptr, which is ambiguous and causes
compilation error. Remove that overload from the overload set by explicitly
qualifying the call.
Reported in https://github.com/boostorg/filesystem/pull/260.
C++23 std::string_view added a range constructor that is constrained with
a concept check that in particular checks if the range is contiguous. In
that check, the range iterator type is checked. Since fs::path members now
test whether the source argument is convertible to std::string_view, that
concept check is performed whenever the overload resolution or SFINAE check
is performed. This caused a problem if the check was performed before
fs::path::iterator is defined, since the result of the check formally
changes when the iterator gets defined.
To work around this, move any fs::path non-template member functions that
call to other members (including constructors) which may involve overload
resolution or SFINAE checks that might require testing whether
std::string_view is constructible from fs::path out of fs::path definition
and past the fs::path::iterator definition.
This was also reported to gcc team:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106808
Path traits and relevant path members were reworked to better support
wider range of types that are compatible with path constructors, assignment
and appending members. Added support for C++17 std::string_view,
boost::string_view and boost::container::string as the possible string
types accepted by path members.
Also extended support for types convertible to one of the string types.
Previously, user's type had to be convertible to a string with a character
type that matches the native path character type. Now all supported character
types are acceptable.
Additionally, restricted members accepting a pair of iterators to only accept
iterators whose value types are one of the supported path character types.
Lastly, path::compare and comparison operators now only accept path arguments,
relying on path conversion constructors to do the job of supporting various
source types. Also removed noexcept from compare as it is using lex_compare
and iterators internally and those can throw.
Closes https://github.com/boostorg/filesystem/issues/208.
Users are advised to use string types and iterators instead of containers
to construct/assign/append to paths.
In v4, the support for containers is removed.
During its operation, weakly_canonical would call status() on the path
consisting only from the root name of the input path. This would fail
with ERROR_INVALID_FUNCTION if the root name starts with the "\\?\" prefix,
as the root name path is not absolute.
To fix this, we don't check the status of the root name path (which is
not the correct check anyways as it tests the current directory on the
corresponding drive for existence, which is not what we want). Additionally,
avoid calling status() on the paths containing dot and dot-dot elements
during the weakly_canonical execution for the same reason - the "\\?\"
prefix disables most of the path processing in Windows APIs, including
dot and dot-dot elements resolution.
Fixes https://github.com/boostorg/filesystem/issues/247.
This follows up the previous update for POSIX.
The new implementation of remove_all on Windows Vista and later uses
NtCreateFile internal function in order to open files relative to
a previously opened directory handle, similar to POSIX openat.
Furthermore, querying file status and removing the file is now also
done through file handles to avoid performing path resolutions.
Closes https://github.com/boostorg/filesystem/issues/224.
The previous implementation could still allow for following symlinks
while remove_all is running if a directory was replaced with a symlink
higher in the tree than remove_all is currently processing. This was
reported here:
https://github.com/boostorg/filesystem/issues/224#issuecomment-1183738097
The solution is to use POSIX.1-2008 *at APIs to prevent symlink resolution
higher in the directory tree while iterating over the subtree in remove_all.
This required updating the directory iterator construction interface so that
it is possible to pass the base directory fd and return fd of the directory
used by the iterator. This is done via platform-specific params that are
currently defined only for POSIX. Additionally, status, symlink_status and
remove were extended to accept the base directory fd as well.
Other systems, including Windows, remain vulnerable.
Related to https://github.com/boostorg/filesystem/issues/224.
The copy_file_range implementation of copy_file used to set incorrect sendfile
fallback if copy_file_range failed with ENOSYS. The fallback would skip
checking the filesystem type for whether it is supported by sendfile.
Also, wrapped sendfile and copy_file_range implementations in structs to
silence clang warnings about using C++11 feature in C++03 mode: the functions
are in an anonymous namespace and therefore have internal linkage, and
pointers to such functions are not allowed to be used in non-type template
parameters in C++03.
Clang triggers -Wunused-function for get_dir_itr_imp_extra_data, which
may or may not be used depending on the target platform. Better to disable
the warning rather than add macro checks.
Reproduce the workaround for GetFileInformationByHandleEx returning
ERROR_INVALID_PARAMETER when querying FILE_ATTRIBUTE_TAG_INFO on FAT/exFAT
filesystems in directory iterator construction.
Fixes https://github.com/boostorg/filesystem/issues/237.
Apparently, GetFileInformationByHandleEx(FileAttributeTagInfo) fails
with ERROR_INVALID_PARAMETER on FAT/exFAT filesystems, which used to
be interpreted as "file not found" result in (symlink_)status(). The
file is clearly present since it was successfully opened before,
and the error is presumably because the filesystem does not support
reparse points and cannot return a ReparseTag.
Check that error code and also ERROR_NOT_SUPPORTED for good measure
and fall back to the legacy code path that works for FAT/exFAT.
Fixes https://github.com/boostorg/filesystem/issues/236.