Some filesystems have regular files with generated content. Such files have
arbitrary size, including zero, but have actual content. Linux system calls
sendfile or copy_file_range will not copy contents of such files, so we must
use a read/write loop to handle them.
Check the type of the source filesystem before using sendfile or
copy_file_range and fallback to the read/write loop if it matches one of
the blacklisted filesystems: procfs, sysfs, tracefs or debugfs.
Also, added a test to verify that copy_file works on procfs.
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.
These options allow to synchronize the copied data and attributes with
the permanent storage. Note that by default on POSIX systems copy_file
used to synchronize data in previous releases, and this commit changes
this. The caller now has to explicitly request syncing, as it has
significant performance implications.
Closes https://github.com/boostorg/filesystem/issues/186.
At least HP-UX is known to leave the file descriptor open if close() returns
EINTR. On other systems (Linux, BSD, Solaris, AIX) the file descriptor
is closed in the same situation, and closing it again may potentially close
the wrong descriptor if it is reused by another thread. We introduce
close_fd internal helper to abstract away these platform differences.
By defining these new config macros the user can configure the library
to avoid using some system APIs even if they are detected as available
by the library build scripts. This can be useful in case if the API
is known to consistently fail at runtime on the target system.
Related to https://github.com/boostorg/filesystem/issues/172.
create_directories used to ignore errors returned by status()
calls issued internally. The operation would likely fail anyway,
but the error codes returned by create_directories would be incorrect.
Also, it is better to terminate the operation as early as possible
when an error is encountered.
Reported in https://github.com/boostorg/filesystem/issues/182.
This makes a difference in case if Boost.Filesystem is linked statically into
user's application. In this case filesystem_error used to be not marked as
publicly visible, which could make it impossible to catch the exception if
it crossed shared library boundary. By marking the class as publicly visible
we ensure that RTTI is always visible, even in static builds.
The exported members are also marked with dllexport/dllimport attributes
for compatibility with Windows.
Presumably, there's some sort of mismatch between times returned by time()
and file creation timestamps when converted to time_t, which can sometimes
result in a test failure. The pauses ensure there's enough distance
between start, finish and file creation timestamps for the discrepancy
to not matter. Also added debug output.
This is to work around the problem of Boost.Build not being able to detect
default address-model when it is 32 (as it is for MSVC 9.0 to 11.0 in
AppVeyor CI). As a result, the build fails because cl.exe cannot be found.
Related to https://github.com/boostorg/build/issues/659.
Functions for stat/statx abstraction become unused when either of
the two APIs is used, which triggers clang warnings.
Ported copy_directory to statx and removed the BOOST_COPY_DIRECTORY
macro. One less usage of stat().
Removed workarounds for MSVC versions older than 7.0. Use portable
typedef for 64-bit integers.
Marked some internal functions inline. Removed zero initialization
of stat structs prior to stat calls, which is expected to initialize
the struct anyway.
The Linux statx system call allows to specify the data the caller is
interested in. This has the potential of improving performance
if some information is expensive to provide.
Also, changed hard_link_count to return static_cast<uintmax_t>(-1)
in case of errors. Changed file_size to report ENOSYS instead of
EPERM when the operation is invoked on a non-regular file.
This follows C++20 definition, which returns a minimum representable time
point value in case of error.
Also, slight refactoring of last_write_time setter function and a fix
to ensure the error code is cleared incase of success.
Ubuntu Focal has a recent enough Linux kernel and glibc to support
statx syscall.
Also switch clang-9 to Ubuntu Bionic and added linux-libc-dev package
installation to test the case when statx is supported by the kernel
but the wrapper in libc is not available.