This commit changes behavior of directory_entry constructors and modifiers
that change the stored path in v4: the methods will now automatically query
the filesystem for the file status instead of leaving the cached data
default-initialized. This means that the paths passed to directory_entry
must be valid, otherwise an error will be returned. Filesystem querying
is implemented in the new directory_entry::refresh methods.
The constructors and modifiers that accepted file_status arguments are
now removed in v4. The cached file statuses are an implementation detail,
and eventually we may want to add more cached data, as we add more observers
to directory_entry.
Also added a few file type observers to directory_entry. These observers
allow to avoid querying the filesystem if the full file status is not cached
but the file type is (i.e. when permissions are not cached). This is the case
with readdir-based implementation of directory_iterator, if the underlying
C library supports dirent::d_type field.
recursive_directory_iterator has been updated to use the added file type
observers instead of querying the full status. This may improve performance
of directory iteration.
Closes https://github.com/boostorg/filesystem/issues/288.
This fixes hard compilation error when the passed type is not an iterator
at all. As a result, path constructors from iterators are no longer
selected by the compiler in overload resolution in users' code, when
the caller is passing an initializer list with a pair of non-iterator
elements. Added a test for this fix.
Also, use integral_constant to implement boolean type traits.
Fixes https://github.com/boostorg/filesystem/issues/287.
Path comparison operators that accept arbitrary path source types now require
the other argument to be exactly path. This prevents the compiler from picking
those operators when the other argument is convertible to path. This can happen
even when neither of the arguments are actually paths, e.g. when the
comparison operators are brought into the current scope by a using directive.
Fixes https://github.com/boostorg/filesystem/issues/285.
GetFileInformationByHandleEx with information classes that produce FILE_ID_128
fail with a special error code ERROR_INVALID_LEVEL when the filesystem is
SMBv1. Treat this error code the same as ERROR_INVALID_PARAMETER.
Fixes https://github.com/boostorg/filesystem/issues/284.
If the file handle for a directory in a SMBv1 share was opened with
FILE_READ_ATTRIBUTES access mode, GetFileInformationByHandleEx with
FileAttributeTagInfo returns FILE_ATTRIBUTE_NORMAL in the attributes, which
affected status, symlink_status and everything depending on those.
Work around this Windows bug by adding FILE_READ_EA everywhere where we need
attributes to be correct.
Also, use GENERIC_READ access mode when we call GetFileTime on the handle
afterwards. GetFileTime documentation explicitly mentions that GENERIC_READ
is required for it.
Fixes https://github.com/boostorg/filesystem/issues/282.
The previous strategy of force-inlining methods that are dependent
on the library version is not effective with MSVC in debug mode,
when linking the static library. The compiler does not inline
methods despite the markup, and during linking the static library
with the user's module the linker may or may not pick up user's
definitions of these methods.
When building the library, do not define path methods that depend
on the library version. Instead, explicitly call v4 internal methods
throughout the implementation. This way the compiled library does not
contain v4 versions of these methods, and therefore does not conflict
with user's definitions of these methods.
Fixes https://github.com/boostorg/filesystem/issues/279.
v4 remove_filename works similar to std::filesystem, i.e. preserves
the trailing directory separator after removing the filename.
v3 remove_filename works as before. Its behavior is also useful in
v4, so added a new method remove_filename_and_trailing_separators
with the same behavior.
Also added replace_filename that was previously missing.
remove_filename discrepancy from std::filesystem was reported in:
https://github.com/boostorg/filesystem/issues/271
This resolves build error if examples are compiled for multiple
target configurations. When building tutorial examples, only one
target is supposed to be used.
This causes ambiguities in users' code where the previously added conversion
from user-defined types that have a conversion to one of the path source
types:
struct my_class
{
operator std::string() const;
};
std::string to_string(std::string const&);
std::string to_string(boost::filesystem::path const&);
to_string(my_class());
The above call is ambiguous as the conversion operator in my_class and
a converting constructor in boost::filesystem::path from my_class are
both available and have equivalent ranks.
Removing the conversion constructors from boost::filesystem::path
means users will have to explicitly cast their types to one of the
path source types before constructing path.
In order to preserve backward compatibility with operator== and operator!=
for paths that also accepted source types (path::string_type,
const path::value_type*), we have to update path::compare and comparison
operators to accept types that are convertible to source types.
Fixes https://github.com/boostorg/filesystem/issues/273.
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.