402 Commits

Author SHA1 Message Date
Andrey Semashev
bf29b81a36 Added a workaround for dirfd being a macro on FreeBSD 9 and older.
Fixes https://github.com/boostorg/filesystem/issues/328.
2024-10-03 13:26:18 +03:00
Andrey Semashev
fbd23ee0e0 Prevent templated path members from accepting args convertible to path.
This forces the non-templated overloads accepting path to be chosen instead
of the templated members that expect arguments converible to Source.

This resolves overload resolution ambiguities, when the argument of a
user-defined type is convertible to path and multiple other types that qualify
as Source. By preferring the conversion to path we avoid testing other
conversion paths that may be ambiguous.

Fixes https://github.com/boostorg/filesystem/issues/326.
2024-09-30 02:53:06 +03:00
Andrey Semashev
11beaba974 Reimplement canonical in terms of GetFinalPathNameByHandleW on Windows.
This moves the common part of v3 and v4 canonical() to a separate
function and changes the Windows implementation to use
GetFinalPathNameByHandleW system call. As a side effect, this converts
drive names to upper case, which makes paths more interoperable.

Additionally, on POSIX systems, avoid adding a trailing directory
separator if the input path has one (which may be the case in v4). This
is consistent with libstdc++ and MSVC implementations of std::filesystem.

Fixes https://github.com/boostorg/filesystem/issues/325.
2024-09-16 21:19:10 +03:00
Andrey Semashev
41a990ef14 Fix weakly_canonical with relative input paths.
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.
2024-07-03 15:02:47 +03:00
Andrey Semashev
9f8dea7353 Don't throw in directory_entry::refresh if the file doesn't exist.
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.
2024-06-29 14:00:49 +03:00
Andrey Semashev
5d16e6bd00 Fixed file_size and is_empty for symlinks on Windows. Reworked is_empty.
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.
2024-06-18 22:33:20 +03:00
Andrey Semashev
a0c8edba38 Documentation fixes. 2024-03-24 00:10:13 +03:00
Andrey Semashev
9f6bf1a433 Use openat-style APIs on Windows to implement recursive_dir_iterator.
This makes recursive_directory_iterator more protected against filesystem
changes during iteration.
2024-02-18 03:25:47 +03:00
Andrey Semashev
7eece0064a On POSIX systems, use *at APIs in recursive_directory_iterator.
This makes the iterator more resilient to concurrent filesystem
modifications.
2024-02-12 01:07:44 +03:00
Andrey Semashev
a668706004 Added docs for replacements for removed APIs in convenience.hpp. 2024-01-27 01:06:38 +03:00
Andrey Semashev
47dd78b32f Fixed mismatching HTML tags in docs. 2024-01-20 03:21:56 +03:00
Andrey Semashev
5156746cd9 Partly restore documentation of the removed deprecated APIs.
This partly restores documentation removed in
5df060e95ca844fe91b29001b4ae22bdb65635c6 and moves the features from
"deprecated" table to a new "removed" table. This provides users
with suggested replacements for the removed features.
2024-01-18 20:16:04 +03:00
Andrey Semashev
5df060e95c Removed deprecated APIs.
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.
2024-01-14 17:48:44 +03:00
Andrey Semashev
fc243122b9 Added a copy_options::ignore_attribute_errors option for copy_file/copy.
The new option allows to ignore errors while copying file attributes
(but not file contents).

Closes https://github.com/boostorg/filesystem/issues/179.
2024-01-13 17:22:16 +03:00
Andrey Semashev
7ff596a8df v4: Make absolute() produce a trailing slash for empty input path.
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.
2024-01-08 20:42:32 +03:00
Andrey Semashev
1426ca53b4 v4: Make equivalent() fail if only one of the paths exists.
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.
2024-01-08 02:35:29 +03:00
Andrey Semashev
56c5f6ac1d Updated canonical docs to only require absolute(p, base) to exist.
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.
2024-01-07 14:46:17 +03:00
Andrey Semashev
d7e6e3100a Added storage preallocation for the target file in copy_file on Linux.
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.
2024-01-05 15:41:01 +03:00
Andrey Semashev
cf135d3f69 Fix weakly_canonical for relative paths that don't exist in the filesystem.
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.
2024-01-04 19:25:32 +03:00
Andrey Semashev
9361213a91 Added a unique_path overload taking a single error_code& argument.
The overload uses the default path model.

Also, express the default model in native characters to avoid unnecessary
character code conversion.
2024-01-04 18:47:50 +03:00
Andrey Semashev
b87d2790e7 v4: Avoid converting slashes in path root name in path::make_preferred.
Similarly to other methods, make_preferred is only supposed to affect
directory separators and not the slashes that are part of the path
root name.
2024-01-04 04:07:46 +03:00
Andrey Semashev
0f890633c3 v4: Avoid converting slashes in root names in path::lexically_normal.
lexically_normal is supposed to convert directory separators, so it
should not modify the path root name.
2024-01-04 04:07:46 +03:00
Andrey Semashev
18b4e2f94c Rework path::generic_path to remove duplicate separators and retain root name.
std::filesystem::path::generic_string mandates that the returned string
uses *single* forward slashes for directory separators, which means
any duplicates must be removed. Boost.Filesystem now follows this definition,
and also documents that forward slashes are used for directory separators.

Additionally, since only directory separators are supposed to be affected,
in v4 avoid converting any slashes that are part of the path root name. This
is the case on Windows with UNC paths and Windows-specific path prefixes.
Keep v3 behavior unchanged for backward compatibility.

Closes https://github.com/boostorg/filesystem/issues/299.
2024-01-04 04:07:34 +03:00
Andrey Semashev
a5f4935baf Documentation fixes. 2024-01-04 00:27:23 +03:00
Andrey Semashev
ae5197fe7d Removed invalid character from docs. 2024-01-03 03:46:54 +03:00
Andrey Semashev
53eabaeabb Added a note about deprecation of Windows versions prior to 10. 2023-10-08 20:51:02 +03:00
Andrey Semashev
be82eff289 Removed string_file.hpp that was deprecated in 1.79.0. 2023-10-04 19:40:55 +03:00
Andrey Semashev
4c621f1577 Removed support for Windows CE that was deprecated in 1.79.0. 2023-10-04 19:40:47 +03:00
Andrey Semashev
f805447b75 Improve robustness of date/time conversions on Windows.
Assume time_t is signed on Windows, which means negative values are
possible and represent dates before January 1, 1970 (which is also
allowed by FILETIME).

In order to increase the effective range of time_t, add/subtract
the offset value in seconds rather than in 100 ns units.

Perform range checks and report error if the input date/time, whether
in time_t or FILETIME, would cause an overflow during conversion.

Fixes https://github.com/boostorg/filesystem/issues/293.
2023-09-24 01:18:36 +03:00
Andrey Semashev
fe07038a2d Drop C++03 compilers from CI, C++11 is now a requirement.
Due to other Boost libraries that Boost.Filesystem depends on dropping
support for C++03, Boost.Filesystem now requires C++11 as a minimum.
Thus remove C++03 testing from CI and update docs accordingly.
2023-09-08 00:01:50 +03:00
Andrey Semashev
16805b5a11 Added missing error code clearing in directory_entry members.
Fixes https://github.com/boostorg/filesystem/issues/291.
2023-08-28 19:47:55 +03:00
Andrey Semashev
e65ddb6ef2 Relax access rights for GetFileTime on Windows.
GetFileTime is documented to require GENERIC_READ access right, but this causes
problems if the file is opened by another process without FILE_SHARE_READ.
In practice, FILE_READ_ATTRIBUTES works, and FILE_READ_EA is also added for
good measure, in case if it matters for SMBv1.

If this doesn't work in some case, we might switch to
GetFileInformationByHandle(Ex) in the future.

Fixes https://github.com/boostorg/filesystem/issues/290.
2023-07-12 19:17:25 +03:00
Andrey Semashev
7bb038fcb8 Added a new cstdio.hpp header with fopen overload.
This overload takes filesystem::path as its first argument to support
wide character paths on Windows. Other than this, the overload is
equivalent to std::fopen.
2023-06-12 15:02:30 +03:00
Andrey Semashev
b1bf547a55 Added more file type testing functions.
Also, make namespace-scope file testing functions for directory_entry
forward to member functions for better efficiency.
2023-06-11 20:56:20 +03:00
Andrey Semashev
d508d4950f Add dir_entry::refresh and file type observers. Use them in recursive dir_it.
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.
2023-06-04 20:18:50 +03:00
Andrey Semashev
277da85cab Make fstream types move constructible/assignable.
If the standard library fstream types are movable, Boost.Filesystem
counterparts are now movable as well.

Closes https://github.com/boostorg/filesystem/issues/280.
2023-05-22 23:21:56 +03:00
Andrey Semashev
39b0f3a1fe Check that the type is an iterator in is_path_source_iterator.
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.
2023-05-21 17:27:12 +03:00
Andrey Semashev
615881f5ba Added more Windows error codes as indication for unsupported dir info class.
Also extracted the check for the error codes to a separate function for
easier maintenance.

Closes https://github.com/boostorg/filesystem/issues/286.
2023-05-13 16:08:21 +03:00
Andrey Semashev
396eef1398 Restrict generic path comparison operators to avoid ambiguities with std lib.
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.
2023-05-08 00:11:37 +03:00
Andrey Semashev
fcc1bf3eca Added another worksround for SMBv1, this time in directory iterators.
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.
2023-04-13 19:48:42 +03:00
Andrey Semashev
1db4474d1a Work around incorrect attributes reported on Windows for dirs in SMBv1 shares.
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.
2023-03-31 13:22:03 +03:00
Andrey Semashev
7745d57ca8 Added a note about C++03 deprecation. 2023-03-29 02:08:19 +03:00
Andrey Semashev
656c5922c0 Expanded description of Windows path prefixes. 2023-02-12 02:27:06 +03:00
Andrey Semashev
7509619c9e Updated library version selection to avoid ODR violations.
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.
2023-02-08 01:00:54 +03:00
Andrey Semashev
b6ecf3013d Added v4 path::remove_filename. Added path::replace_filename.
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
2023-02-05 20:25:50 +03:00
Andrey Semashev
0c8931b74f Make installing tutorial example binaries explicit.
This resolves build error if examples are compiled for multiple
target configurations. When building tutorial examples, only one
target is supposed to be used.
2023-02-05 01:10:31 +03:00
Andrey Semashev
b3acfca7c5 Updated tutorial to remove references to scripts that were long deleted.
Closes https://github.com/boostorg/filesystem/issues/276.
2023-02-05 00:13:41 +03:00
Andrey Semashev
5cefe7890f Remove path converting constructors from types convertible to path sources.
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.
2023-02-04 19:55:17 +03:00
Andrey Semashev
141727b568 Treat dedup files as regular files on Windows.
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.
2022-12-03 02:15:13 +03:00
Andrey Semashev
8b71cb11a3 Added more fallbacks to directory_iterator construction.
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.
2022-12-02 16:23:24 +03:00