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.
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.
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.
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.
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.
Another process could replace the directory being processed by remove_all
with a symlink after remove_all called symlink_status but before
it creates a directory iterator. As a result, remove_all would remove
the linked directory contents instead of removing the symlink.
On POSIX systems that support fdopendir and O_NOFOLLOW flag for open(2),
this can be prevented by opening the directory with O_NOFOLLOW before
iterating. This will fail if the directory was replaced with a symlink.
No protection on other systems.
Reported in https://github.com/boostorg/filesystem/issues/224.
Apparently, gcc does not support the attribute on Mac OS 11.4. Since
we can't tell if other systems aren't supported as well, it's better
to check with a configure check. As a side effect, this might add
support for more compilers.
Closes https://github.com/boostorg/filesystem/issues/199.
In order to avoid hardcoding library dependencies recursively for the
configure checks performed in CMake build scripts, we generate the list
of all include directories. If there is a unified Boost include tree,
we can use that and avoid filesystem scanning.
Instead of using atomic<> to access global function pointers, use raw
pointers and atomic_ref to access them safely in multi-threaded builds.
This allows to ensure constant initialization of the function pointers,
even in C++03. This also solves the problem of undefined dynamic
initialization order that we previously tried to solve with the
init_priority attribute. The attribute turns out to not work if the
pointers were raw pointers (in single-threaded builds). It is also
not supported by Intel Compiler and possibly other, which required
us to avoid using the function pointer for fill_random.
The resulting code should be simpler and more portable. In order to
check for C++20 std::atomic_ref availability, the older check for <atomic>
header was replaced with a check for std::atomic_ref. If not available,
we're using Boost.Atomic, as before.
This forces definition of _WIN32_WINNT by Boost.WinAPI, which is important
for CopyFileEx and related symbols to be defined. Platform SDK from MSVC-8
does not define the macro by default, which caused compilation errors
previously.
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.
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.
This should fix readdir(_r) on 32-bit systems, which was not 64-bit after
commit c758552338e40ffe4c0bde127a81a753a3366fa7 because _FILE_OFFSET_BITS=64
was not defined in directory.cpp. Also, there were filesystem-related system
calls in unique_path.cpp, where the macro was not defined either. Including
the platform header in all source files is useful for possible future changes
that may require the platform-specific macros.
Closes https://github.com/boostorg/filesystem/pull/150.
The check depends on Boost.Predef and Boost.WinAPI. Unfortunately,
we cannot use their CMake targets in check_cxx_source_compiles because
they may not yet be defined at the point of inclusion of
filesystem/CMakeLists.txt by the superproject. Thus we have to manually
specify include path to the monolithic include tree. And bcrypt library.
We intentionally do not specify include paths for Boost.Predef and
Boost.WinAPI because that would require to also specify paths of their
dependencies, and this is not an acceptable maintenance burden.
Directory iteration components were moved to separate files to simplify
maintenance of operations.hpp/cpp.
directory_iterator implementation on POSIX platforms has been reworked
to only allocate internal buffer when readdir_r is used. When readdir
is used, the dirent structure returned by readdir is used directly, which
eliminates the potential of buffer overrun in case if some directory name
exceeds the buffer size. This also removes the need to copy dirent members
into the buffer, which improves performance and simplifies maintenance.
For buffer size we now use the max path size as opposed to max filename
size. This is done to minimize the possibility of buffer overruns when
readdir_r is used.
On Windows, use Boost.WinAPI to configure the default target Windows version.
This removes WINVER and _WIN32_WINNT defines in Boost.Filesystem as these
macros should be defined by Boost.WinAPI now.
Additionally, exception.hpp and directory.hpp includes in operations.hpp are
marked as deprecated as operations.hpp do not need those components. Users
are encouraged to include the new headers explicitly in their code, as needed.
This simplifies maintenance of the operations.hpp/cpp files.
Also, moved BOOST_FILESYSTEM_SOURCE definition to the build system files
instead of defining it in every source file.
- CMake file only supports add_subdirectory workflow.
- Compiles boost filesystem (without name mangling).
- Provides target Boost::filesystem to link against.
- Does NOT compile/run unit tests (yet) and
doesn't support installation.