aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2022-08-29 07:42:14 +0300
committerthegeorg <thegeorg@yandex-team.com>2022-08-29 07:42:14 +0300
commit08b42c5732ff484354c4ca8adba3b002b117d122 (patch)
treee9757bdde5d9e8a10b187efffacbe8ea9282a0f5
parent9f0fa80273f73bc1848572d7bd8a08ad530e438e (diff)
downloadydb-08b42c5732ff484354c4ca8adba3b002b117d122.tar.gz
Update contrib/restricted/boost/filesystem to 1.80.0
-rw-r--r--contrib/restricted/boost/filesystem/CMakeLists.darwin.txt45
-rw-r--r--contrib/restricted/boost/filesystem/CMakeLists.linux.txt48
-rw-r--r--contrib/restricted/boost/filesystem/CMakeLists.txt42
-rw-r--r--contrib/restricted/boost/filesystem/include/boost/filesystem/detail/header.hpp2
-rw-r--r--contrib/restricted/boost/filesystem/include/boost/filesystem/detail/utf8_codecvt_facet.hpp6
-rw-r--r--contrib/restricted/boost/filesystem/include/boost/filesystem/directory.hpp30
-rw-r--r--contrib/restricted/boost/filesystem/include/boost/filesystem/file_status.hpp4
-rw-r--r--contrib/restricted/boost/filesystem/include/boost/filesystem/fstream.hpp3
-rw-r--r--contrib/restricted/boost/filesystem/include/boost/filesystem/operations.hpp79
-rw-r--r--contrib/restricted/boost/filesystem/include/boost/filesystem/path.hpp18
-rw-r--r--contrib/restricted/boost/filesystem/include/boost/filesystem/path_traits.hpp14
-rw-r--r--contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp15
-rw-r--r--contrib/restricted/boost/filesystem/src/directory.cpp139
-rw-r--r--contrib/restricted/boost/filesystem/src/error_handling.hpp44
-rw-r--r--contrib/restricted/boost/filesystem/src/exception.cpp4
-rw-r--r--contrib/restricted/boost/filesystem/src/operations.cpp1224
-rw-r--r--contrib/restricted/boost/filesystem/src/path.cpp4
-rw-r--r--contrib/restricted/boost/filesystem/src/path_traits.cpp4
-rw-r--r--contrib/restricted/boost/filesystem/src/portability.cpp4
-rw-r--r--contrib/restricted/boost/filesystem/src/posix_tools.hpp17
-rw-r--r--contrib/restricted/boost/filesystem/src/unique_path.cpp4
-rw-r--r--contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp4
-rw-r--r--contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp4
-rw-r--r--contrib/restricted/boost/filesystem/src/windows_file_codecvt.hpp4
-rw-r--r--contrib/restricted/boost/filesystem/src/windows_tools.hpp106
25 files changed, 1289 insertions, 579 deletions
diff --git a/contrib/restricted/boost/filesystem/CMakeLists.darwin.txt b/contrib/restricted/boost/filesystem/CMakeLists.darwin.txt
new file mode 100644
index 00000000000..167b59b73ef
--- /dev/null
+++ b/contrib/restricted/boost/filesystem/CMakeLists.darwin.txt
@@ -0,0 +1,45 @@
+
+# This file was gererated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_library(restricted-boost-filesystem)
+target_compile_options(restricted-boost-filesystem PRIVATE
+ -DBOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF
+ -Wno-everything
+)
+target_include_directories(restricted-boost-filesystem PUBLIC
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/include
+)
+target_link_libraries(restricted-boost-filesystem PUBLIC
+ contrib-libs-cxxsupp
+ restricted-boost-assert
+ restricted-boost-atomic
+ restricted-boost-config
+ restricted-boost-container_hash
+ restricted-boost-core
+ restricted-boost-detail
+ restricted-boost-io
+ restricted-boost-iterator
+ restricted-boost-range
+ restricted-boost-smart_ptr
+ restricted-boost-static_assert
+ restricted-boost-system
+ restricted-boost-type_traits
+)
+target_sources(restricted-boost-filesystem PRIVATE
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/directory.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/exception.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/operations.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/path.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/path_traits.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/portability.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/unique_path.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp
+)
diff --git a/contrib/restricted/boost/filesystem/CMakeLists.linux.txt b/contrib/restricted/boost/filesystem/CMakeLists.linux.txt
new file mode 100644
index 00000000000..476398fbe51
--- /dev/null
+++ b/contrib/restricted/boost/filesystem/CMakeLists.linux.txt
@@ -0,0 +1,48 @@
+
+# This file was gererated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_library(restricted-boost-filesystem)
+target_compile_options(restricted-boost-filesystem PUBLIC
+ -DBOOST_FILESYSTEM_HAS_POSIX_AT_APIS
+)
+target_compile_options(restricted-boost-filesystem PRIVATE
+ -DBOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF
+ -Wno-everything
+)
+target_include_directories(restricted-boost-filesystem PUBLIC
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/include
+)
+target_link_libraries(restricted-boost-filesystem PUBLIC
+ contrib-libs-cxxsupp
+ restricted-boost-assert
+ restricted-boost-atomic
+ restricted-boost-config
+ restricted-boost-container_hash
+ restricted-boost-core
+ restricted-boost-detail
+ restricted-boost-io
+ restricted-boost-iterator
+ restricted-boost-range
+ restricted-boost-smart_ptr
+ restricted-boost-static_assert
+ restricted-boost-system
+ restricted-boost-type_traits
+)
+target_sources(restricted-boost-filesystem PRIVATE
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/directory.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/exception.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/operations.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/path.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/path_traits.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/portability.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/unique_path.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp
+ ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp
+)
diff --git a/contrib/restricted/boost/filesystem/CMakeLists.txt b/contrib/restricted/boost/filesystem/CMakeLists.txt
index 167b59b73ef..fc7b1ee73ce 100644
--- a/contrib/restricted/boost/filesystem/CMakeLists.txt
+++ b/contrib/restricted/boost/filesystem/CMakeLists.txt
@@ -6,40 +6,8 @@
# original buildsystem will not be accepted.
-
-add_library(restricted-boost-filesystem)
-target_compile_options(restricted-boost-filesystem PRIVATE
- -DBOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF
- -Wno-everything
-)
-target_include_directories(restricted-boost-filesystem PUBLIC
- ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/include
-)
-target_link_libraries(restricted-boost-filesystem PUBLIC
- contrib-libs-cxxsupp
- restricted-boost-assert
- restricted-boost-atomic
- restricted-boost-config
- restricted-boost-container_hash
- restricted-boost-core
- restricted-boost-detail
- restricted-boost-io
- restricted-boost-iterator
- restricted-boost-range
- restricted-boost-smart_ptr
- restricted-boost-static_assert
- restricted-boost-system
- restricted-boost-type_traits
-)
-target_sources(restricted-boost-filesystem PRIVATE
- ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp
- ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/directory.cpp
- ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/exception.cpp
- ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/operations.cpp
- ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/path.cpp
- ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/path_traits.cpp
- ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/portability.cpp
- ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/unique_path.cpp
- ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp
- ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp
-)
+if (APPLE)
+ include(CMakeLists.darwin.txt)
+elseif (UNIX AND NOT APPLE)
+ include(CMakeLists.linux.txt)
+endif()
diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/header.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/header.hpp
index 2d121e40f1f..10f49a658e9 100644
--- a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/header.hpp
+++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/header.hpp
@@ -37,6 +37,8 @@
#pragma GCC diagnostic push
// unused parameter 'arg'
#pragma GCC diagnostic ignored "-Wunused-parameter"
+// unused function 'foo'
+#pragma GCC diagnostic ignored "-Wunused-function"
#endif
diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/utf8_codecvt_facet.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/utf8_codecvt_facet.hpp
index 0011cc71cff..4df9a7c620d 100644
--- a/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/utf8_codecvt_facet.hpp
+++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/detail/utf8_codecvt_facet.hpp
@@ -9,6 +9,8 @@
#include <boost/filesystem/config.hpp>
+#include <boost/filesystem/detail/header.hpp>
+
#define BOOST_UTF8_BEGIN_NAMESPACE \
namespace boost { \
namespace filesystem { \
@@ -26,4 +28,6 @@
#undef BOOST_UTF8_END_NAMESPACE
#undef BOOST_UTF8_DECL
-#endif
+#include <boost/filesystem/detail/footer.hpp>
+
+#endif // BOOST_FILESYSTEM_UTF8_CODECVT_FACET_HPP
diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/directory.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/directory.hpp
index 66e1dd9bcbf..68b13638e11 100644
--- a/contrib/restricted/boost/filesystem/include/boost/filesystem/directory.hpp
+++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/directory.hpp
@@ -142,8 +142,8 @@ public:
bool operator>=(directory_entry const& rhs) const BOOST_NOEXCEPT { return m_path >= rhs.m_path; }
private:
- BOOST_FILESYSTEM_DECL file_status get_status(system::error_code* ec = 0) const;
- BOOST_FILESYSTEM_DECL file_status get_symlink_status(system::error_code* ec = 0) const;
+ BOOST_FILESYSTEM_DECL file_status get_status(system::error_code* ec = NULL) const;
+ BOOST_FILESYSTEM_DECL file_status get_symlink_status(system::error_code* ec = NULL) const;
private:
boost::filesystem::path m_path;
@@ -263,6 +263,7 @@ struct dir_itr_imp :
public boost::intrusive_ref_counter< dir_itr_imp >
{
#ifdef BOOST_WINDOWS_API
+ bool close_handle;
unsigned char extra_data_format;
std::size_t current_offset;
#endif
@@ -271,6 +272,7 @@ struct dir_itr_imp :
dir_itr_imp() BOOST_NOEXCEPT :
#ifdef BOOST_WINDOWS_API
+ close_handle(false),
extra_data_format(0u),
current_offset(0u),
#endif
@@ -284,7 +286,9 @@ struct dir_itr_imp :
BOOST_FILESYSTEM_DECL static void operator delete(void* p) BOOST_NOEXCEPT;
};
-BOOST_FILESYSTEM_DECL void directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, system::error_code* ec);
+struct directory_iterator_params;
+
+BOOST_FILESYSTEM_DECL void directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, directory_iterator_params* params, system::error_code* ec);
BOOST_FILESYSTEM_DECL void directory_iterator_increment(directory_iterator& it, system::error_code* ec);
} // namespace detail
@@ -304,7 +308,7 @@ class directory_iterator :
{
friend class boost::iterator_core_access;
- friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, system::error_code* ec);
+ friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, detail::directory_iterator_params* params, system::error_code* ec);
friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_increment(directory_iterator& it, system::error_code* ec);
public:
@@ -314,17 +318,17 @@ public:
// separate translation unit dll's, so forward to detail functions
explicit directory_iterator(path const& p, BOOST_SCOPED_ENUM_NATIVE(directory_options) opts = directory_options::none)
{
- detail::directory_iterator_construct(*this, p, static_cast< unsigned int >(opts), 0);
+ detail::directory_iterator_construct(*this, p, static_cast< unsigned int >(opts), NULL, NULL);
}
directory_iterator(path const& p, system::error_code& ec) BOOST_NOEXCEPT
{
- detail::directory_iterator_construct(*this, p, static_cast< unsigned int >(directory_options::none), &ec);
+ detail::directory_iterator_construct(*this, p, static_cast< unsigned int >(directory_options::none), NULL, &ec);
}
directory_iterator(path const& p, BOOST_SCOPED_ENUM_NATIVE(directory_options) opts, system::error_code& ec) BOOST_NOEXCEPT
{
- detail::directory_iterator_construct(*this, p, static_cast< unsigned int >(opts), &ec);
+ detail::directory_iterator_construct(*this, p, static_cast< unsigned int >(opts), NULL, &ec);
}
BOOST_DEFAULTED_FUNCTION(directory_iterator(directory_iterator const& that), : m_imp(that.m_imp) {})
@@ -360,7 +364,7 @@ private:
return m_imp->dir_entry;
}
- void increment() { detail::directory_iterator_increment(*this, 0); }
+ void increment() { detail::directory_iterator_increment(*this, NULL); }
bool equal(directory_iterator const& rhs) const BOOST_NOEXCEPT
{
@@ -516,7 +520,7 @@ public:
explicit recursive_directory_iterator(path const& dir_path)
{
- detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(directory_options::none), 0);
+ detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(directory_options::none), NULL);
}
recursive_directory_iterator(path const& dir_path, system::error_code& ec)
@@ -526,7 +530,7 @@ public:
recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(directory_options) opts)
{
- detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), 0);
+ detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), NULL);
}
recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(directory_options) opts, system::error_code& ec)
@@ -538,7 +542,7 @@ public:
// Deprecated constructors
recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(symlink_option) opts)
{
- detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), 0);
+ detail::recursive_directory_iterator_construct(*this, dir_path, static_cast< unsigned int >(opts), NULL);
}
recursive_directory_iterator(path const& dir_path, BOOST_SCOPED_ENUM_NATIVE(symlink_option) opts, system::error_code& ec) BOOST_NOEXCEPT
@@ -592,7 +596,7 @@ public:
void pop()
{
- detail::recursive_directory_iterator_pop(*this, 0);
+ detail::recursive_directory_iterator_pop(*this, NULL);
}
void pop(system::error_code& ec) BOOST_NOEXCEPT
@@ -639,7 +643,7 @@ private:
return *m_imp->m_stack.back();
}
- void increment() { detail::recursive_directory_iterator_increment(*this, 0); }
+ void increment() { detail::recursive_directory_iterator_increment(*this, NULL); }
bool equal(recursive_directory_iterator const& rhs) const BOOST_NOEXCEPT
{
diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/file_status.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/file_status.hpp
index 484efdaa23e..90eca99e84a 100644
--- a/contrib/restricted/boost/filesystem/include/boost/filesystem/file_status.hpp
+++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/file_status.hpp
@@ -139,12 +139,12 @@ public:
// for VC++, GCC, and probably other compilers, that =default is not used with noexcept
// functions. GCC is not even consistent for the same release on different platforms.
- BOOST_CONSTEXPR file_status(const file_status& rhs) BOOST_NOEXCEPT :
+ BOOST_CONSTEXPR file_status(file_status const& rhs) BOOST_NOEXCEPT :
m_value(rhs.m_value),
m_perms(rhs.m_perms)
{
}
- BOOST_CXX14_CONSTEXPR file_status& operator=(const file_status& rhs) BOOST_NOEXCEPT
+ BOOST_CXX14_CONSTEXPR file_status& operator=(file_status const& rhs) BOOST_NOEXCEPT
{
m_value = rhs.m_value;
m_perms = rhs.m_perms;
diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/fstream.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/fstream.hpp
index b70c901602a..124ab398413 100644
--- a/contrib/restricted/boost/filesystem/include/boost/filesystem/fstream.hpp
+++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/fstream.hpp
@@ -15,6 +15,7 @@
#include <boost/filesystem/config.hpp>
#include <boost/filesystem/path.hpp>
+#include <cstddef>
#include <iosfwd>
#include <fstream>
@@ -71,7 +72,7 @@ public:
public:
basic_filebuf< charT, traits >* open(path const& p, std::ios_base::openmode mode)
{
- return std::basic_filebuf< charT, traits >::open(BOOST_FILESYSTEM_C_STR(p), mode) ? this : 0;
+ return std::basic_filebuf< charT, traits >::open(BOOST_FILESYSTEM_C_STR(p), mode) ? this : NULL;
}
};
diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/operations.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/operations.hpp
index 9ccd20d041c..856de7c1a5a 100644
--- a/contrib/restricted/boost/filesystem/include/boost/filesystem/operations.hpp
+++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/operations.hpp
@@ -30,8 +30,9 @@
#include <boost/core/scoped_enum.hpp>
#include <boost/system/error_code.hpp>
#include <boost/cstdint.hpp>
-#include <string>
+#include <cstddef>
#include <ctime>
+#include <string>
#include <boost/filesystem/detail/header.hpp> // must be the last #include
@@ -89,78 +90,78 @@ BOOST_SCOPED_ENUM_DECLARE_END(copy_option)
namespace detail {
BOOST_FILESYSTEM_DECL
-path absolute(path const& p, path const& base, system::error_code* ec = 0);
+path absolute(path const& p, path const& base, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-file_status status(path const& p, system::error_code* ec = 0);
+file_status status(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-file_status symlink_status(path const& p, system::error_code* ec = 0);
+file_status symlink_status(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-bool is_empty(path const& p, system::error_code* ec = 0);
+bool is_empty(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-path initial_path(system::error_code* ec = 0);
+path initial_path(system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-path canonical(path const& p, path const& base, system::error_code* ec = 0);
+path canonical(path const& p, path const& base, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-void copy(path const& from, path const& to, unsigned int options, system::error_code* ec = 0);
+void copy(path const& from, path const& to, unsigned int options, system::error_code* ec = NULL);
#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED)
BOOST_FILESYSTEM_DECL
-void copy_directory(path const& from, path const& to, system::error_code* ec = 0);
+void copy_directory(path const& from, path const& to, system::error_code* ec = NULL);
#endif
BOOST_FILESYSTEM_DECL
-bool copy_file(path const& from, path const& to, // See ticket #2925
- unsigned int options, system::error_code* ec = 0); // see copy_options for options
+bool copy_file(path const& from, path const& to, // See ticket #2925
+ unsigned int options, system::error_code* ec = NULL); // see copy_options for options
BOOST_FILESYSTEM_DECL
-void copy_symlink(path const& existing_symlink, path const& new_symlink, system::error_code* ec = 0);
+void copy_symlink(path const& existing_symlink, path const& new_symlink, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-bool create_directories(path const& p, system::error_code* ec = 0);
+bool create_directories(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-bool create_directory(path const& p, const path* existing, system::error_code* ec = 0);
+bool create_directory(path const& p, const path* existing, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-void create_directory_symlink(path const& to, path const& from, system::error_code* ec = 0);
+void create_directory_symlink(path const& to, path const& from, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-void create_hard_link(path const& to, path const& from, system::error_code* ec = 0);
+void create_hard_link(path const& to, path const& from, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-void create_symlink(path const& to, path const& from, system::error_code* ec = 0);
+void create_symlink(path const& to, path const& from, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-path current_path(system::error_code* ec = 0);
+path current_path(system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-void current_path(path const& p, system::error_code* ec = 0);
+void current_path(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-bool equivalent(path const& p1, path const& p2, system::error_code* ec = 0);
+bool equivalent(path const& p1, path const& p2, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-boost::uintmax_t file_size(path const& p, system::error_code* ec = 0);
+boost::uintmax_t file_size(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-boost::uintmax_t hard_link_count(path const& p, system::error_code* ec = 0);
+boost::uintmax_t hard_link_count(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-std::time_t creation_time(path const& p, system::error_code* ec = 0);
+std::time_t creation_time(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-std::time_t last_write_time(path const& p, system::error_code* ec = 0);
+std::time_t last_write_time(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-void last_write_time(path const& p, const std::time_t new_time, system::error_code* ec = 0);
+void last_write_time(path const& p, const std::time_t new_time, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-void permissions(path const& p, perms prms, system::error_code* ec = 0);
+void permissions(path const& p, perms prms, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-path read_symlink(path const& p, system::error_code* ec = 0);
+path read_symlink(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-path relative(path const& p, path const& base, system::error_code* ec = 0);
+path relative(path const& p, path const& base, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-bool remove(path const& p, system::error_code* ec = 0);
+bool remove(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-boost::uintmax_t remove_all(path const& p, system::error_code* ec = 0);
+boost::uintmax_t remove_all(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-void rename(path const& old_p, path const& new_p, system::error_code* ec = 0);
+void rename(path const& old_p, path const& new_p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-void resize_file(path const& p, uintmax_t size, system::error_code* ec = 0);
+void resize_file(path const& p, uintmax_t size, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-space_info space(path const& p, system::error_code* ec = 0);
+space_info space(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-path system_complete(path const& p, system::error_code* ec = 0);
+path system_complete(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-path temp_directory_path(system::error_code* ec = 0);
+path temp_directory_path(system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-path unique_path(path const& p, system::error_code* ec = 0);
+path unique_path(path const& p, system::error_code* ec = NULL);
BOOST_FILESYSTEM_DECL
-path weakly_canonical(path const& p, path const& base, system::error_code* ec = 0);
+path weakly_canonical(path const& p, path const& base, system::error_code* ec = NULL);
} // namespace detail
@@ -447,12 +448,12 @@ inline bool create_directories(path const& p, system::error_code& ec) BOOST_NOEX
inline bool create_directory(path const& p)
{
- return detail::create_directory(p, 0);
+ return detail::create_directory(p, NULL);
}
inline bool create_directory(path const& p, system::error_code& ec) BOOST_NOEXCEPT
{
- return detail::create_directory(p, 0, &ec);
+ return detail::create_directory(p, NULL, &ec);
}
inline bool create_directory(path const& p, path const& existing)
diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/path.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/path.hpp
index 2f06c866e17..0554c987a19 100644
--- a/contrib/restricted/boost/filesystem/include/boost/filesystem/path.hpp
+++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/path.hpp
@@ -209,7 +209,7 @@ public:
template< class Source >
path(Source const& source, typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value
- >::type* = 0)
+ >::type* = NULL)
{
path_traits::dispatch(source, m_pathname);
}
@@ -274,7 +274,7 @@ public:
template< class Source >
path(Source const& source, codecvt_type const& cvt, typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value
- >::type* = 0)
+ >::type* = NULL)
{
path_traits::dispatch(source, m_pathname, cvt);
}
@@ -282,7 +282,7 @@ public:
path(const value_type* begin, const value_type* end) : m_pathname(begin, end) {}
template< class InputIterator >
- path(InputIterator begin, InputIterator end, typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator > >::type* = 0)
+ path(InputIterator begin, InputIterator end, typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator > >::type* = NULL)
{
if (begin != end)
{
@@ -295,7 +295,7 @@ public:
path(const value_type* begin, const value_type* end, codecvt_type const&) : m_pathname(begin, end) {}
template< class InputIterator >
- path(InputIterator begin, InputIterator end, codecvt_type const& cvt, typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator > >::type* = 0)
+ path(InputIterator begin, InputIterator end, codecvt_type const& cvt, typename boost::disable_if< path_detail::is_native_char_ptr< InputIterator > >::type* = NULL)
{
if (begin != end)
{
@@ -1183,7 +1183,7 @@ template< typename T >
inline typename boost::enable_if< boost::is_same< T, path >, std::size_t >::type hash_value(T const& p) BOOST_NOEXCEPT
{
#ifdef BOOST_WINDOWS_API
- std::size_t seed = 0;
+ std::size_t seed = 0u;
for (typename T::value_type const* it = p.c_str(); *it; ++it)
hash_combine(seed, *it == L'/' ? L'\\' : *it);
return seed;
@@ -1359,14 +1359,14 @@ inline std::wstring path::generic_string< std::wstring >(codecvt_type const& cvt
namespace path_traits { // without codecvt
inline void convert(const char* from,
- const char* from_end, // 0 for null terminated MBCS
+ const char* from_end, // NULL for null terminated MBCS
std::wstring& to)
{
convert(from, from_end, to, path::codecvt());
}
inline void convert(const wchar_t* from,
- const wchar_t* from_end, // 0 for null terminated MBCS
+ const wchar_t* from_end, // NULL for null terminated MBCS
std::string& to)
{
convert(from, from_end, to, path::codecvt());
@@ -1375,13 +1375,13 @@ inline void convert(const wchar_t* from,
inline void convert(const char* from, std::wstring& to)
{
BOOST_ASSERT(!!from);
- convert(from, 0, to, path::codecvt());
+ convert(from, NULL, to, path::codecvt());
}
inline void convert(const wchar_t* from, std::string& to)
{
BOOST_ASSERT(!!from);
- convert(from, 0, to, path::codecvt());
+ convert(from, NULL, to, path::codecvt());
}
} // namespace path_traits
diff --git a/contrib/restricted/boost/filesystem/include/boost/filesystem/path_traits.hpp b/contrib/restricted/boost/filesystem/include/boost/filesystem/path_traits.hpp
index 7f6dea0473f..e4f9b52c0dc 100644
--- a/contrib/restricted/boost/filesystem/include/boost/filesystem/path_traits.hpp
+++ b/contrib/restricted/boost/filesystem/include/boost/filesystem/path_traits.hpp
@@ -147,40 +147,40 @@ inline bool empty(T (&x)[N])
// value types differ ---------------------------------------------------------------//
//
-// A from_end argument of 0 is less efficient than a known end, so use only if needed
+// A from_end argument of NULL is less efficient than a known end, so use only if needed
// with codecvt
BOOST_FILESYSTEM_DECL
void convert(const char* from,
- const char* from_end, // 0 for null terminated MBCS
+ const char* from_end, // NULL for null terminated MBCS
std::wstring& to, codecvt_type const& cvt);
BOOST_FILESYSTEM_DECL
void convert(const wchar_t* from,
- const wchar_t* from_end, // 0 for null terminated MBCS
+ const wchar_t* from_end, // NULL for null terminated MBCS
std::string& to, codecvt_type const& cvt);
inline void convert(const char* from, std::wstring& to, codecvt_type const& cvt)
{
BOOST_ASSERT(from);
- convert(from, 0, to, cvt);
+ convert(from, NULL, to, cvt);
}
inline void convert(const wchar_t* from, std::string& to, codecvt_type const& cvt)
{
BOOST_ASSERT(from);
- convert(from, 0, to, cvt);
+ convert(from, NULL, to, cvt);
}
// without codecvt
inline void convert(const char* from,
- const char* from_end, // 0 for null terminated MBCS
+ const char* from_end, // NULL for null terminated MBCS
std::wstring& to);
inline void convert(const wchar_t* from,
- const wchar_t* from_end, // 0 for null terminated MBCS
+ const wchar_t* from_end, // NULL for null terminated MBCS
std::string& to);
inline void convert(const char* from, std::wstring& to);
diff --git a/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp b/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp
index 501f78f103c..72db677a09c 100644
--- a/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp
+++ b/contrib/restricted/boost/filesystem/src/codecvt_error_category.cpp
@@ -22,6 +22,8 @@
#include "private_config.hpp"
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
+
//--------------------------------------------------------------------------------------//
namespace boost {
@@ -29,6 +31,13 @@ namespace filesystem {
namespace {
+#if (defined(BOOST_GCC) && BOOST_GCC >= 40600) || defined(BOOST_CLANG)
+#pragma GCC diagnostic push
+// '(anonymous namespace)::codecvt_error_cat' has virtual functions but non-virtual destructor
+// This is not a problem as instances of codecvt_error_cat are never destroyed through a pointer to base.
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+
class codecvt_error_cat BOOST_FINAL :
public boost::system::error_category
{
@@ -68,6 +77,10 @@ std::string codecvt_error_cat::message(int ev) const
return str;
}
+#if (defined(BOOST_GCC) && BOOST_GCC >= 40600) || defined(BOOST_CLANG)
+#pragma GCC diagnostic pop
+#endif
+
} // unnamed namespace
BOOST_FILESYSTEM_DECL boost::system::error_category const& codecvt_error_category() BOOST_NOEXCEPT
@@ -103,3 +116,5 @@ const codecvt_error_category_initializer g_codecvt_error_category_initializer;
} // namespace filesystem
} // namespace boost
+
+#include <boost/filesystem/detail/footer.hpp>
diff --git a/contrib/restricted/boost/filesystem/src/directory.cpp b/contrib/restricted/boost/filesystem/src/directory.cpp
index cbe8319cf03..6a3e1dc7319 100644
--- a/contrib/restricted/boost/filesystem/src/directory.cpp
+++ b/contrib/restricted/boost/filesystem/src/directory.cpp
@@ -72,6 +72,8 @@
#include "error_handling.hpp"
#include "private_config.hpp"
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
+
// BOOST_FILESYSTEM_STATUS_CACHE enables file_status cache in
// dir_itr_increment. The config tests are placed here because some of the
// macros being tested come from dirent.h.
@@ -376,7 +378,7 @@ error_code dir_itr_increment(dir_itr_imp& imp, fs::path& filename, fs::file_stat
return error_code();
}
-error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::path const& dir, unsigned int opts, fs::path& first_filename, fs::file_status&, fs::file_status&)
+error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::path const& dir, unsigned int opts, directory_iterator_params* params, fs::path& first_filename, fs::file_status&, fs::file_status&)
{
std::size_t extra_size = 0u;
#if defined(BOOST_FILESYSTEM_USE_READDIR_R)
@@ -409,7 +411,11 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::
if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u)
flags |= O_NOFOLLOW;
+#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ int fd = ::openat(params ? params->basedir_fd : AT_FDCWD, dir.c_str(), flags);
+#else
int fd = ::open(dir.c_str(), flags);
+#endif
if (BOOST_UNLIKELY(fd < 0))
{
const int err = errno;
@@ -445,6 +451,11 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::
// Force initial readdir call by the caller. This will initialize the actual first filename and statuses.
first_filename.assign(".");
+#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
+ if (params)
+ params->iterator_fd = fd;
+#endif
+
imp.swap(pimpl);
return error_code();
}
@@ -586,7 +597,7 @@ extra_data_format g_extra_data_format = file_directory_information_format;
/*!
* \brief Extra buffer size for GetFileInformationByHandleEx-based or NtQueryDirectoryFile-based directory iterator.
- *
+ *
* Must be large enough to accommodate at least one FILE_DIRECTORY_INFORMATION or *_DIR_INFO struct and one filename.
* NTFS, VFAT, exFAT support filenames up to 255 UTF-16/UCS-2 characters. ReFS supports filenames up to 32768 UTF-16 characters.
*/
@@ -599,7 +610,8 @@ inline system::error_code dir_itr_close(dir_itr_imp& imp) BOOST_NOEXCEPT
if (imp.handle != NULL)
{
- ::CloseHandle(imp.handle);
+ if (BOOST_LIKELY(imp.close_handle))
+ ::CloseHandle(imp.handle);
imp.handle = NULL;
}
@@ -751,54 +763,76 @@ done:
return error_code();
}
-error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::path const& dir, unsigned int opts, fs::path& first_filename, fs::file_status& sf, fs::file_status& symlink_sf)
+error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::path const& dir, unsigned int opts, directory_iterator_params* params, fs::path& first_filename, fs::file_status& sf, fs::file_status& symlink_sf)
{
boost::intrusive_ptr< detail::dir_itr_imp > pimpl(new (dir_itr_extra_size) detail::dir_itr_imp());
if (BOOST_UNLIKELY(!pimpl))
return make_error_code(system::errc::not_enough_memory);
- DWORD flags = FILE_FLAG_BACKUP_SEMANTICS;
- if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u)
- flags |= FILE_FLAG_OPEN_REPARSE_POINT;
- handle_wrapper h(create_file_handle(dir, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, flags));
- if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE))
+ GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api);
+
+ handle_wrapper h;
+ HANDLE iterator_handle;
+ bool close_handle = true;
+ if (params != NULL && params->use_handle != INVALID_HANDLE_VALUE)
{
- return_last_error:
- DWORD error = ::GetLastError();
- return error_code(error, system_category());
+ // Operate on externally provided handle, which must be a directory handle
+ iterator_handle = params->use_handle;
+ close_handle = params->close_handle;
}
-
- GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api);
- if (BOOST_LIKELY(get_file_information_by_handle_ex != NULL))
+ else
{
- file_attribute_tag_info info;
- BOOL res = get_file_information_by_handle_ex(h.handle, file_attribute_tag_info_class, &info, sizeof(info));
- if (BOOST_UNLIKELY(!res))
- goto return_last_error;
-
- if (BOOST_UNLIKELY((info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0u))
- return make_error_code(system::errc::not_a_directory);
-
+ DWORD flags = FILE_FLAG_BACKUP_SEMANTICS;
if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u)
+ flags |= FILE_FLAG_OPEN_REPARSE_POINT;
+
+ iterator_handle = h.handle = create_file_handle(dir, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, flags);
+ if (BOOST_UNLIKELY(iterator_handle == INVALID_HANDLE_VALUE))
{
- if ((info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0u && is_reparse_point_tag_a_symlink(info.ReparseTag))
- return make_error_code(system::errc::too_many_symbolic_link_levels);
+ return_last_error:
+ DWORD error = ::GetLastError();
+ return error_code(error, system_category());
}
- }
- else
- {
- BY_HANDLE_FILE_INFORMATION info;
- BOOL res = ::GetFileInformationByHandle(h.handle, &info);
- if (BOOST_UNLIKELY(!res))
- goto return_last_error;
- if (BOOST_UNLIKELY((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0u))
- return make_error_code(system::errc::not_a_directory);
+ if (BOOST_LIKELY(get_file_information_by_handle_ex != NULL))
+ {
+ file_attribute_tag_info info;
+ BOOL res = get_file_information_by_handle_ex(iterator_handle, file_attribute_tag_info_class, &info, sizeof(info));
+ if (BOOST_UNLIKELY(!res))
+ {
+ // On FAT/exFAT filesystems requesting FILE_ATTRIBUTE_TAG_INFO returns ERROR_INVALID_PARAMETER. See the comment in symlink_status.
+ DWORD error = ::GetLastError();
+ if (error == ERROR_INVALID_PARAMETER || error == ERROR_NOT_SUPPORTED)
+ goto use_get_file_information_by_handle;
- if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u)
+ return error_code(error, system_category());
+ }
+
+ if (BOOST_UNLIKELY((info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0u))
+ return make_error_code(system::errc::not_a_directory);
+
+ if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u)
+ {
+ if ((info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0u && is_reparse_point_tag_a_symlink(info.ReparseTag))
+ return make_error_code(system::errc::too_many_symbolic_link_levels);
+ }
+ }
+ else
{
- if ((info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0u && is_reparse_point_a_symlink_ioctl(h.handle))
- return make_error_code(system::errc::too_many_symbolic_link_levels);
+ use_get_file_information_by_handle:
+ BY_HANDLE_FILE_INFORMATION info;
+ BOOL res = ::GetFileInformationByHandle(iterator_handle, &info);
+ if (BOOST_UNLIKELY(!res))
+ goto return_last_error;
+
+ if (BOOST_UNLIKELY((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0u))
+ return make_error_code(system::errc::not_a_directory);
+
+ if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u)
+ {
+ if ((info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0u && is_reparse_point_a_symlink_ioctl(h.handle))
+ return make_error_code(system::errc::too_many_symbolic_link_levels);
+ }
}
}
@@ -807,7 +841,7 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::
{
case file_id_extd_dir_info_format:
{
- if (!get_file_information_by_handle_ex(h.handle, file_id_extd_directory_restart_info_class, extra_data, dir_itr_extra_size))
+ if (!get_file_information_by_handle_ex(iterator_handle, file_id_extd_directory_restart_info_class, extra_data, dir_itr_extra_size))
{
DWORD error = ::GetLastError();
@@ -841,7 +875,7 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::
case file_full_dir_info_format:
fallback_to_file_full_dir_info_format:
{
- if (!get_file_information_by_handle_ex(h.handle, file_full_directory_restart_info_class, extra_data, dir_itr_extra_size))
+ if (!get_file_information_by_handle_ex(iterator_handle, file_full_directory_restart_info_class, extra_data, dir_itr_extra_size))
{
DWORD error = ::GetLastError();
@@ -870,7 +904,7 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::
case file_id_both_dir_info_format:
fallback_to_file_id_both_dir_info:
{
- if (!get_file_information_by_handle_ex(h.handle, file_id_both_directory_restart_info_class, extra_data, dir_itr_extra_size))
+ if (!get_file_information_by_handle_ex(iterator_handle, file_id_both_directory_restart_info_class, extra_data, dir_itr_extra_size))
{
DWORD error = ::GetLastError();
@@ -898,7 +932,7 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::
io_status_block iosb;
boost::winapi::NTSTATUS_ status = nt_query_directory_file
(
- h.handle,
+ iterator_handle,
NULL, // Event
NULL, // ApcRoutine
NULL, // ApcContext
@@ -933,8 +967,10 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::
break;
}
- pimpl->handle = h.handle;
+
+ pimpl->handle = iterator_handle;
h.handle = INVALID_HANDLE_VALUE;
+ pimpl->close_handle = close_handle;
done:
imp.swap(pimpl);
@@ -947,7 +983,8 @@ inline system::error_code dir_itr_close(dir_itr_imp& imp) BOOST_NOEXCEPT
{
if (imp.handle != NULL)
{
- ::FindClose(imp.handle);
+ if (BOOST_LIKELY(imp.close_handle))
+ ::FindClose(imp.handle);
imp.handle = NULL;
}
@@ -973,7 +1010,7 @@ done:
return error_code();
}
-error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::path const& dir, unsigned int opts, fs::path& first_filename, fs::file_status& sf, fs::file_status& symlink_sf)
+error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::path const& dir, unsigned int opts, directory_iterator_params*, fs::path& first_filename, fs::file_status& sf, fs::file_status& symlink_sf)
{
boost::intrusive_ptr< detail::dir_itr_imp > pimpl(new (static_cast< std::size_t >(0u)) detail::dir_itr_imp());
if (BOOST_UNLIKELY(!pimpl))
@@ -1001,6 +1038,8 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::
return error_code(error, system_category());
}
+ pimpl->close_handle = true;
+
first_filename = data.cFileName;
set_file_statuses(data.dwFileAttributes, NULL, first_filename, sf, symlink_sf);
@@ -1039,7 +1078,7 @@ dir_itr_imp::~dir_itr_imp() BOOST_NOEXCEPT
}
BOOST_FILESYSTEM_DECL
-void directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, system::error_code* ec)
+void directory_iterator_construct(directory_iterator& it, path const& p, unsigned int opts, directory_iterator_params* params, system::error_code* ec)
{
if (BOOST_UNLIKELY(p.empty()))
{
@@ -1055,7 +1094,7 @@ void directory_iterator_construct(directory_iterator& it, path const& p, unsigne
boost::intrusive_ptr< detail::dir_itr_imp > imp;
path filename;
file_status file_stat, symlink_file_stat;
- system::error_code result = dir_itr_create(imp, p, opts, filename, file_stat, symlink_file_stat);
+ system::error_code result = dir_itr_create(imp, p, opts, params, filename, file_stat, symlink_file_stat);
while (true)
{
@@ -1169,7 +1208,7 @@ void recursive_directory_iterator_construct(recursive_directory_iterator& it, pa
ec->clear();
directory_iterator dir_it;
- detail::directory_iterator_construct(dir_it, dir_path, opts, ec);
+ detail::directory_iterator_construct(dir_it, dir_path, opts, NULL, ec);
if ((ec && *ec) || dir_it == directory_iterator())
return;
@@ -1307,8 +1346,8 @@ inline push_directory_result recursive_directory_iterator_push_directory(detail:
file_status symlink_stat;
- // if we are not recursing into symlinks, we are going to have to know if the
- // stack top is a symlink, so get symlink_status and verify no error occurred
+ // If we are not recursing into symlinks, we are going to have to know if the
+ // stack top is a symlink, so get symlink_status and verify no error occurred.
if ((imp->m_options & static_cast< unsigned int >(directory_options::follow_directory_symlink)) == 0u ||
(imp->m_options & static_cast< unsigned int >(directory_options::skip_dangling_symlinks)) != 0u)
{
@@ -1452,3 +1491,5 @@ void recursive_directory_iterator_increment(recursive_directory_iterator& it, sy
} // namespace filesystem
} // namespace boost
+
+#include <boost/filesystem/detail/footer.hpp>
diff --git a/contrib/restricted/boost/filesystem/src/error_handling.hpp b/contrib/restricted/boost/filesystem/src/error_handling.hpp
index cd6a72e17fd..97590a87120 100644
--- a/contrib/restricted/boost/filesystem/src/error_handling.hpp
+++ b/contrib/restricted/boost/filesystem/src/error_handling.hpp
@@ -24,6 +24,8 @@
#include <boost/winapi/error_codes.hpp>
#endif
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
+
namespace boost {
namespace filesystem {
@@ -86,6 +88,33 @@ typedef boost::winapi::DWORD_ err_t;
#if !defined(STATUS_ACCESS_DENIED)
#define STATUS_ACCESS_DENIED ((boost::winapi::NTSTATUS_)0xC0000022l)
#endif
+#if !defined(STATUS_OBJECT_NAME_NOT_FOUND)
+#define STATUS_OBJECT_NAME_NOT_FOUND ((boost::winapi::NTSTATUS_)0xC0000034l)
+#endif
+#if !defined(STATUS_OBJECT_PATH_NOT_FOUND)
+#define STATUS_OBJECT_PATH_NOT_FOUND ((boost::winapi::NTSTATUS_)0xC000003Al)
+#endif
+#if !defined(STATUS_NOT_SUPPORTED)
+#define STATUS_NOT_SUPPORTED ((boost::winapi::NTSTATUS_)0xC00000BBl)
+#endif
+#if !defined(STATUS_BAD_NETWORK_PATH)
+#define STATUS_BAD_NETWORK_PATH ((boost::winapi::NTSTATUS_)0xC00000BEl)
+#endif
+#if !defined(STATUS_DEVICE_DOES_NOT_EXIST)
+#define STATUS_DEVICE_DOES_NOT_EXIST ((boost::winapi::NTSTATUS_)0xC00000C0l)
+#endif
+#if !defined(STATUS_BAD_NETWORK_NAME)
+#define STATUS_BAD_NETWORK_NAME ((boost::winapi::NTSTATUS_)0xC00000CCl)
+#endif
+#if !defined(STATUS_DIRECTORY_NOT_EMPTY)
+#define STATUS_DIRECTORY_NOT_EMPTY ((boost::winapi::NTSTATUS_)0xC0000101l)
+#endif
+#if !defined(STATUS_NOT_A_DIRECTORY)
+#define STATUS_NOT_A_DIRECTORY ((boost::winapi::NTSTATUS_)0xC0000103l)
+#endif
+#if !defined(STATUS_NOT_FOUND)
+#define STATUS_NOT_FOUND ((boost::winapi::NTSTATUS_)0xC0000225l)
+#endif
//! Converts NTSTATUS error codes to Win32 error codes for reporting
inline boost::winapi::DWORD_ translate_ntstatus(boost::winapi::NTSTATUS_ status)
@@ -104,11 +133,24 @@ inline boost::winapi::DWORD_ translate_ntstatus(boost::winapi::NTSTATUS_ status)
case static_cast< boost::winapi::ULONG_ >(STATUS_NO_MORE_FILES):
return boost::winapi::ERROR_NO_MORE_FILES_;
case static_cast< boost::winapi::ULONG_ >(STATUS_NO_SUCH_DEVICE):
+ case static_cast< boost::winapi::ULONG_ >(STATUS_DEVICE_DOES_NOT_EXIST):
return boost::winapi::ERROR_DEV_NOT_EXIST_;
case static_cast< boost::winapi::ULONG_ >(STATUS_NO_SUCH_FILE):
+ case static_cast< boost::winapi::ULONG_ >(STATUS_OBJECT_NAME_NOT_FOUND):
+ case static_cast< boost::winapi::ULONG_ >(STATUS_OBJECT_PATH_NOT_FOUND):
return boost::winapi::ERROR_FILE_NOT_FOUND_;
case static_cast< boost::winapi::ULONG_ >(STATUS_ACCESS_DENIED):
return boost::winapi::ERROR_ACCESS_DENIED_;
+ case static_cast< boost::winapi::ULONG_ >(STATUS_BAD_NETWORK_PATH):
+ return boost::winapi::ERROR_BAD_NETPATH_;
+ case static_cast< boost::winapi::ULONG_ >(STATUS_BAD_NETWORK_NAME):
+ return boost::winapi::ERROR_BAD_NET_NAME_;
+ case static_cast< boost::winapi::ULONG_ >(STATUS_DIRECTORY_NOT_EMPTY):
+ return boost::winapi::ERROR_DIR_NOT_EMPTY_;
+ case static_cast< boost::winapi::ULONG_ >(STATUS_NOT_A_DIRECTORY):
+ return boost::winapi::ERROR_DIRECTORY_; // The directory name is invalid
+ case static_cast< boost::winapi::ULONG_ >(STATUS_NOT_FOUND):
+ return boost::winapi::ERROR_NOT_FOUND_;
// map "invalid info class" to "not supported" as this error likely indicates that the kernel does not support what we request
case static_cast< boost::winapi::ULONG_ >(STATUS_INVALID_INFO_CLASS):
default:
@@ -173,4 +215,6 @@ inline bool error(err_t error_num, path const& p1, path const& p2, system::error
} // namespace filesystem
} // namespace boost
+#include <boost/filesystem/detail/footer.hpp>
+
#endif // BOOST_FILESYSTEM_SRC_ERROR_HANDLING_HPP_
diff --git a/contrib/restricted/boost/filesystem/src/exception.cpp b/contrib/restricted/boost/filesystem/src/exception.cpp
index b0480a8b8e6..91ee1c90a9b 100644
--- a/contrib/restricted/boost/filesystem/src/exception.cpp
+++ b/contrib/restricted/boost/filesystem/src/exception.cpp
@@ -19,7 +19,7 @@
#include "error_handling.hpp"
-#include <boost/config/abi_prefix.hpp> // must be the last #include
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
namespace boost {
namespace filesystem {
@@ -185,4 +185,4 @@ void emit_error(err_t error_num, path const& p1, path const& p2, system::error_c
} // namespace filesystem
} // namespace boost
-#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
+#include <boost/filesystem/detail/footer.hpp>
diff --git a/contrib/restricted/boost/filesystem/src/operations.cpp b/contrib/restricted/boost/filesystem/src/operations.cpp
index 8d2f0adf963..dd636e90637 100644
--- a/contrib/restricted/boost/filesystem/src/operations.cpp
+++ b/contrib/restricted/boost/filesystem/src/operations.cpp
@@ -32,18 +32,21 @@
#include <cstddef>
#include <cstdlib> // for malloc, free
#include <cstring>
-#include <cstdio> // for remove, rename
-#if defined(__QNXNTO__) // see ticket #5355
-#include <stdio.h>
-#endif
#include <cerrno>
+#include <stdio.h> // for rename
+
+// Default to POSIX under Emscripten
+// If BOOST_FILESYSTEM_EMSCRIPTEN_USE_WASI is set, use WASI instead
+#if defined(__wasm) && (!defined(__EMSCRIPTEN__) || defined(BOOST_FILESYSTEM_EMSCRIPTEN_USE_WASI))
+#define BOOST_FILESYSTEM_USE_WASI
+#endif
#ifdef BOOST_POSIX_API
#include <sys/types.h>
#include <sys/stat.h>
-#if defined(__wasm)
+#if defined(BOOST_FILESYSTEM_USE_WASI)
// WASI does not have statfs or statvfs.
#elif !defined(__APPLE__) && \
(!defined(__OpenBSD__) || BOOST_OS_BSD_OPEN >= BOOST_VERSION_NUMBER(4, 4, 0)) && \
@@ -164,6 +167,8 @@ using std::time_t;
#include "error_handling.hpp"
#include "private_config.hpp"
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
+
namespace fs = boost::filesystem;
using boost::filesystem::path;
using boost::filesystem::filesystem_error;
@@ -286,7 +291,7 @@ BOOST_CONSTEXPR_OR_CONST unsigned int symloop_max =
bool is_empty_directory(path const& p, error_code* ec)
{
fs::directory_iterator itr;
- detail::directory_iterator_construct(itr, p, static_cast< unsigned int >(directory_options::none), ec);
+ detail::directory_iterator_construct(itr, p, static_cast< unsigned int >(directory_options::none), NULL, ec);
return itr == fs::directory_iterator();
}
@@ -472,6 +477,130 @@ inline std::size_t get_blksize(struct ::stat const& st) BOOST_NOEXCEPT
#endif // defined(BOOST_FILESYSTEM_USE_STATX)
+//! status() implementation
+file_status status_impl
+(
+ path const& p,
+ error_code* ec
+#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) || defined(BOOST_FILESYSTEM_USE_STATX)
+ , int basedir_fd = AT_FDCWD
+#endif
+)
+{
+#if defined(BOOST_FILESYSTEM_USE_STATX)
+ struct ::statx path_stat;
+ int err = invoke_statx(basedir_fd, p.c_str(), AT_NO_AUTOMOUNT, STATX_TYPE | STATX_MODE, &path_stat);
+#elif defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ struct ::stat path_stat;
+ int err = ::fstatat(basedir_fd, p.c_str(), &path_stat, AT_NO_AUTOMOUNT);
+#else
+ struct ::stat path_stat;
+ int err = ::stat(p.c_str(), &path_stat);
+#endif
+
+ if (err != 0)
+ {
+ err = errno;
+ if (ec) // always report errno, even though some
+ ec->assign(err, system_category()); // errno values are not status_errors
+
+ if (not_found_error(err))
+ return fs::file_status(fs::file_not_found, fs::no_perms);
+
+ if (!ec)
+ BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status", p, error_code(err, system_category())));
+
+ return fs::file_status(fs::status_error);
+ }
+
+#if defined(BOOST_FILESYSTEM_USE_STATX)
+ if (BOOST_UNLIKELY((path_stat.stx_mask & (STATX_TYPE | STATX_MODE)) != (STATX_TYPE | STATX_MODE)))
+ {
+ emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::status");
+ return fs::file_status(fs::status_error);
+ }
+#endif
+
+ const mode_t mode = get_mode(path_stat);
+ if (S_ISDIR(mode))
+ return fs::file_status(fs::directory_file, static_cast< perms >(mode) & fs::perms_mask);
+ if (S_ISREG(mode))
+ return fs::file_status(fs::regular_file, static_cast< perms >(mode) & fs::perms_mask);
+ if (S_ISBLK(mode))
+ return fs::file_status(fs::block_file, static_cast< perms >(mode) & fs::perms_mask);
+ if (S_ISCHR(mode))
+ return fs::file_status(fs::character_file, static_cast< perms >(mode) & fs::perms_mask);
+ if (S_ISFIFO(mode))
+ return fs::file_status(fs::fifo_file, static_cast< perms >(mode) & fs::perms_mask);
+ if (S_ISSOCK(mode))
+ return fs::file_status(fs::socket_file, static_cast< perms >(mode) & fs::perms_mask);
+
+ return fs::file_status(fs::type_unknown);
+}
+
+//! symlink_status() implementation
+file_status symlink_status_impl
+(
+ path const& p,
+ error_code* ec
+#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) || defined(BOOST_FILESYSTEM_USE_STATX)
+ , int basedir_fd = AT_FDCWD
+#endif
+)
+{
+#if defined(BOOST_FILESYSTEM_USE_STATX)
+ struct ::statx path_stat;
+ int err = invoke_statx(basedir_fd, p.c_str(), AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT, STATX_TYPE | STATX_MODE, &path_stat);
+#elif defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ struct ::stat path_stat;
+ int err = ::fstatat(basedir_fd, p.c_str(), &path_stat, AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT);
+#else
+ struct ::stat path_stat;
+ int err = ::lstat(p.c_str(), &path_stat);
+#endif
+
+ if (err != 0)
+ {
+ err = errno;
+ if (ec) // always report errno, even though some
+ ec->assign(err, system_category()); // errno values are not status_errors
+
+ if (not_found_error(err)) // these are not errors
+ return fs::file_status(fs::file_not_found, fs::no_perms);
+
+ if (!ec)
+ BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::symlink_status", p, error_code(err, system_category())));
+
+ return fs::file_status(fs::status_error);
+ }
+
+#if defined(BOOST_FILESYSTEM_USE_STATX)
+ if (BOOST_UNLIKELY((path_stat.stx_mask & (STATX_TYPE | STATX_MODE)) != (STATX_TYPE | STATX_MODE)))
+ {
+ emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::symlink_status");
+ return fs::file_status(fs::status_error);
+ }
+#endif
+
+ const mode_t mode = get_mode(path_stat);
+ if (S_ISREG(mode))
+ return fs::file_status(fs::regular_file, static_cast< perms >(mode) & fs::perms_mask);
+ if (S_ISDIR(mode))
+ return fs::file_status(fs::directory_file, static_cast< perms >(mode) & fs::perms_mask);
+ if (S_ISLNK(mode))
+ return fs::file_status(fs::symlink_file, static_cast< perms >(mode) & fs::perms_mask);
+ if (S_ISBLK(mode))
+ return fs::file_status(fs::block_file, static_cast< perms >(mode) & fs::perms_mask);
+ if (S_ISCHR(mode))
+ return fs::file_status(fs::character_file, static_cast< perms >(mode) & fs::perms_mask);
+ if (S_ISFIFO(mode))
+ return fs::file_status(fs::fifo_file, static_cast< perms >(mode) & fs::perms_mask);
+ if (S_ISSOCK(mode))
+ return fs::file_status(fs::socket_file, static_cast< perms >(mode) & fs::perms_mask);
+
+ return fs::file_status(fs::type_unknown);
+}
+
//! Flushes buffered data and attributes written to the file to permanent storage
inline int full_sync(int fd)
{
@@ -611,130 +740,144 @@ typedef int copy_file_data_t(int infile, int outfile, uintmax_t size, std::size_
//! Pointer to the actual implementation of the copy_file_data implementation
copy_file_data_t* copy_file_data = &copy_file_data_read_write;
+#if defined(BOOST_FILESYSTEM_USE_SENDFILE) || defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE)
+
+//! copy_file_data wrapper that tests if a read/write loop must be used for a given filesystem
+template< typename CopyFileData >
+int check_fs_type(int infile, int outfile, uintmax_t size, std::size_t blksize);
+
+#endif // defined(BOOST_FILESYSTEM_USE_SENDFILE) || defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE)
+
#if defined(BOOST_FILESYSTEM_USE_SENDFILE)
-//! copy_file implementation that uses sendfile loop. Requires sendfile to support file descriptors.
-int copy_file_data_sendfile(int infile, int outfile, uintmax_t size, std::size_t blksize)
+struct copy_file_data_sendfile
{
- // sendfile will not send more than this amount of data in one call
- BOOST_CONSTEXPR_OR_CONST std::size_t max_batch_size = 0x7ffff000u;
- uintmax_t offset = 0u;
- while (offset < size)
- {
- uintmax_t size_left = size - offset;
- std::size_t size_to_copy = max_batch_size;
- if (size_left < static_cast< uintmax_t >(max_batch_size))
- size_to_copy = static_cast< std::size_t >(size_left);
- ssize_t sz = ::sendfile(outfile, infile, NULL, size_to_copy);
- if (BOOST_UNLIKELY(sz < 0))
+ //! copy_file implementation that uses sendfile loop. Requires sendfile to support file descriptors.
+ static int impl(int infile, int outfile, uintmax_t size, std::size_t blksize)
+ {
+ // sendfile will not send more than this amount of data in one call
+ BOOST_CONSTEXPR_OR_CONST std::size_t max_batch_size = 0x7ffff000u;
+ uintmax_t offset = 0u;
+ while (offset < size)
{
- int err = errno;
- if (err == EINTR)
- continue;
-
- if (offset == 0u)
+ uintmax_t size_left = size - offset;
+ std::size_t size_to_copy = max_batch_size;
+ if (size_left < static_cast< uintmax_t >(max_batch_size))
+ size_to_copy = static_cast< std::size_t >(size_left);
+ ssize_t sz = ::sendfile(outfile, infile, NULL, size_to_copy);
+ if (BOOST_UNLIKELY(sz < 0))
{
- // sendfile may fail with EINVAL if the underlying filesystem does not support it
- if (err == EINVAL)
- {
- fallback_to_read_write:
- return copy_file_data_read_write(infile, outfile, size, blksize);
- }
+ int err = errno;
+ if (err == EINTR)
+ continue;
- if (err == ENOSYS)
+ if (offset == 0u)
{
- filesystem::detail::atomic_store_relaxed(copy_file_data, &copy_file_data_read_write);
- goto fallback_to_read_write;
+ // sendfile may fail with EINVAL if the underlying filesystem does not support it
+ if (err == EINVAL)
+ {
+ fallback_to_read_write:
+ return copy_file_data_read_write(infile, outfile, size, blksize);
+ }
+
+ if (err == ENOSYS)
+ {
+ filesystem::detail::atomic_store_relaxed(copy_file_data, &copy_file_data_read_write);
+ goto fallback_to_read_write;
+ }
}
+
+ return err;
}
- return err;
+ offset += sz;
}
- offset += sz;
+ return 0;
}
-
- return 0;
-}
+};
#endif // defined(BOOST_FILESYSTEM_USE_SENDFILE)
#if defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE)
-//! copy_file implementation that uses copy_file_range loop. Requires copy_file_range to support cross-filesystem copying.
-int copy_file_data_copy_file_range(int infile, int outfile, uintmax_t size, std::size_t blksize)
+struct copy_file_data_copy_file_range
{
- // Although copy_file_range does not document any particular upper limit of one transfer, still use some upper bound to guarantee
- // that size_t is not overflown in case if off_t is larger and the file size does not fit in size_t.
- BOOST_CONSTEXPR_OR_CONST std::size_t max_batch_size = 0x7ffff000u;
- uintmax_t offset = 0u;
- while (offset < size)
- {
- uintmax_t size_left = size - offset;
- std::size_t size_to_copy = max_batch_size;
- if (size_left < static_cast< uintmax_t >(max_batch_size))
- size_to_copy = static_cast< std::size_t >(size_left);
- // Note: Use syscall directly to avoid depending on libc version. copy_file_range is added in glibc 2.27.
- // uClibc-ng does not have copy_file_range as of the time of this writing (the latest uClibc-ng release is 1.0.33).
- loff_t sz = ::syscall(__NR_copy_file_range, infile, (loff_t*)NULL, outfile, (loff_t*)NULL, size_to_copy, (unsigned int)0u);
- if (BOOST_UNLIKELY(sz < 0))
+ //! copy_file implementation that uses copy_file_range loop. Requires copy_file_range to support cross-filesystem copying.
+ static int impl(int infile, int outfile, uintmax_t size, std::size_t blksize)
+ {
+ // Although copy_file_range does not document any particular upper limit of one transfer, still use some upper bound to guarantee
+ // that size_t is not overflown in case if off_t is larger and the file size does not fit in size_t.
+ BOOST_CONSTEXPR_OR_CONST std::size_t max_batch_size = 0x7ffff000u;
+ uintmax_t offset = 0u;
+ while (offset < size)
{
- int err = errno;
- if (err == EINTR)
- continue;
-
- if (offset == 0u)
+ uintmax_t size_left = size - offset;
+ std::size_t size_to_copy = max_batch_size;
+ if (size_left < static_cast< uintmax_t >(max_batch_size))
+ size_to_copy = static_cast< std::size_t >(size_left);
+ // Note: Use syscall directly to avoid depending on libc version. copy_file_range is added in glibc 2.27.
+ // uClibc-ng does not have copy_file_range as of the time of this writing (the latest uClibc-ng release is 1.0.33).
+ loff_t sz = ::syscall(__NR_copy_file_range, infile, (loff_t*)NULL, outfile, (loff_t*)NULL, size_to_copy, (unsigned int)0u);
+ if (BOOST_UNLIKELY(sz < 0))
{
- // copy_file_range may fail with EINVAL if the underlying filesystem does not support it.
- // In some RHEL/CentOS 7.7-7.8 kernel versions, copy_file_range on NFSv4 is also known to return EOPNOTSUPP
- // if the remote server does not support COPY, despite that it is not a documented error code.
- // See https://patchwork.kernel.org/project/linux-nfs/patch/20190411183418.4510-1-olga.kornievskaia@gmail.com/
- // and https://bugzilla.redhat.com/show_bug.cgi?id=1783554.
- if (err == EINVAL || err == EOPNOTSUPP)
+ int err = errno;
+ if (err == EINTR)
+ continue;
+
+ if (offset == 0u)
{
+ // copy_file_range may fail with EINVAL if the underlying filesystem does not support it.
+ // In some RHEL/CentOS 7.7-7.8 kernel versions, copy_file_range on NFSv4 is also known to return EOPNOTSUPP
+ // if the remote server does not support COPY, despite that it is not a documented error code.
+ // See https://patchwork.kernel.org/project/linux-nfs/patch/20190411183418.4510-1-olga.kornievskaia@gmail.com/
+ // and https://bugzilla.redhat.com/show_bug.cgi?id=1783554.
+ if (err == EINVAL || err == EOPNOTSUPP)
+ {
#if !defined(BOOST_FILESYSTEM_USE_SENDFILE)
- fallback_to_read_write:
+ fallback_to_read_write:
#endif
- return copy_file_data_read_write(infile, outfile, size, blksize);
- }
+ return copy_file_data_read_write(infile, outfile, size, blksize);
+ }
- if (err == EXDEV)
- {
+ if (err == EXDEV)
+ {
#if defined(BOOST_FILESYSTEM_USE_SENDFILE)
- fallback_to_sendfile:
- return copy_file_data_sendfile(infile, outfile, size, blksize);
+ fallback_to_sendfile:
+ return copy_file_data_sendfile::impl(infile, outfile, size, blksize);
#else
- goto fallback_to_read_write;
+ goto fallback_to_read_write;
#endif
- }
+ }
- if (err == ENOSYS)
- {
+ if (err == ENOSYS)
+ {
#if defined(BOOST_FILESYSTEM_USE_SENDFILE)
- filesystem::detail::atomic_store_relaxed(copy_file_data, &copy_file_data_sendfile);
- goto fallback_to_sendfile;
+ filesystem::detail::atomic_store_relaxed(copy_file_data, &check_fs_type< copy_file_data_sendfile >);
+ goto fallback_to_sendfile;
#else
- filesystem::detail::atomic_store_relaxed(copy_file_data, &copy_file_data_read_write);
- goto fallback_to_read_write;
+ filesystem::detail::atomic_store_relaxed(copy_file_data, &copy_file_data_read_write);
+ goto fallback_to_read_write;
#endif
+ }
}
+
+ return err;
}
- return err;
+ offset += sz;
}
- offset += sz;
+ return 0;
}
-
- return 0;
-}
+};
#endif // defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE)
#if defined(BOOST_FILESYSTEM_USE_SENDFILE) || defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE)
//! copy_file_data wrapper that tests if a read/write loop must be used for a given filesystem
-template< copy_file_data_t* CopyFileData >
+template< typename CopyFileData >
int check_fs_type(int infile, int outfile, uintmax_t size, std::size_t blksize)
{
{
@@ -768,7 +911,7 @@ int check_fs_type(int infile, int outfile, uintmax_t size, std::size_t blksize)
}
}
- return CopyFileData(infile, outfile, size, blksize);
+ return CopyFileData::impl(infile, outfile, size, blksize);
}
#endif // defined(BOOST_FILESYSTEM_USE_SENDFILE) || defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE)
@@ -784,14 +927,14 @@ inline void init_copy_file_data_impl(unsigned int major_ver, unsigned int minor_
#if defined(BOOST_FILESYSTEM_USE_SENDFILE)
// sendfile started accepting file descriptors as the target in Linux 2.6.33
if (major_ver > 2u || (major_ver == 2u && (minor_ver > 6u || (minor_ver == 6u && patch_ver >= 33u))))
- cfd = &check_fs_type< &copy_file_data_sendfile >;
+ cfd = &check_fs_type< copy_file_data_sendfile >;
#endif
#if defined(BOOST_FILESYSTEM_USE_COPY_FILE_RANGE)
// Although copy_file_range appeared in Linux 4.5, it did not support cross-filesystem copying until 5.3.
// copy_file_data_copy_file_range will fallback to copy_file_data_sendfile if copy_file_range returns EXDEV.
if (major_ver > 4u || (major_ver == 4u && minor_ver >= 5u))
- cfd = &check_fs_type< &copy_file_data_copy_file_range >;
+ cfd = &check_fs_type< copy_file_data_copy_file_range >;
#endif
filesystem::detail::atomic_store_relaxed(copy_file_data, cfd);
@@ -827,16 +970,28 @@ const syscall_initializer syscall_init;
#endif // defined(linux) || defined(__linux) || defined(__linux__)
//! remove() implementation
-inline bool remove_impl(path const& p, fs::file_type type, error_code* ec)
+inline bool remove_impl
+(
+ path const& p,
+ fs::file_type type,
+ error_code* ec
+#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ , int basedir_fd = AT_FDCWD
+#endif
+)
{
if (type == fs::file_not_found)
return false;
int res;
+#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ res = ::unlinkat(basedir_fd, p.c_str(), type == fs::directory_file ? AT_REMOVEDIR : 0);
+#else
if (type == fs::directory_file)
res = ::rmdir(p.c_str());
else
res = ::unlink(p.c_str());
+#endif
if (res != 0)
{
@@ -860,7 +1015,7 @@ inline bool remove_impl(path const& p, error_code* ec)
// to remove them.
error_code local_ec;
- fs::file_type type = fs::detail::symlink_status(p, &local_ec).type();
+ fs::file_type type = fs::detail::symlink_status_impl(p, &local_ec).type();
if (BOOST_UNLIKELY(type == fs::status_error))
{
if (!ec)
@@ -874,15 +1029,35 @@ inline bool remove_impl(path const& p, error_code* ec)
}
//! remove_all() implementation
-uintmax_t remove_all_impl(path const& p, error_code* ec)
+uintmax_t remove_all_impl
+(
+ path const& p,
+ error_code* ec
+#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ , int basedir_fd = AT_FDCWD
+#endif
+)
{
+#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ fs::detail::directory_iterator_params params;
+ params.basedir_fd = basedir_fd;
+ params.iterator_fd = -1;
+#endif
+
error_code dit_create_ec;
for (unsigned int attempt = 0u; attempt < remove_all_directory_replaced_retry_count; ++attempt)
{
fs::file_type type;
{
error_code local_ec;
- type = fs::detail::symlink_status(p, &local_ec).type();
+ type = fs::detail::symlink_status_impl
+ (
+ p,
+ &local_ec
+#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ , basedir_fd
+#endif
+ ).type();
if (type == fs::file_not_found)
return 0u;
@@ -901,7 +1076,19 @@ uintmax_t remove_all_impl(path const& p, error_code* ec)
if (type == fs::directory_file) // but not a directory symlink
{
fs::directory_iterator itr;
- fs::detail::directory_iterator_construct(itr, p, static_cast< unsigned int >(directory_options::_detail_no_follow), &dit_create_ec);
+ fs::detail::directory_iterator_construct
+ (
+ itr,
+ p,
+ static_cast< unsigned int >(directory_options::_detail_no_follow),
+#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ &params,
+#else
+ NULL,
+#endif
+ &dit_create_ec
+ );
+
if (BOOST_UNLIKELY(!!dit_create_ec))
{
if (dit_create_ec == error_code(ENOTDIR, system_category()))
@@ -926,7 +1113,18 @@ uintmax_t remove_all_impl(path const& p, error_code* ec)
const fs::directory_iterator end_dit;
while (itr != end_dit)
{
- count += fs::detail::remove_all_impl(itr->path(), ec);
+ count += fs::detail::remove_all_impl
+ (
+#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ itr->path().filename(),
+#else
+ itr->path(),
+#endif
+ ec
+#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ , params.iterator_fd
+#endif
+ );
if (ec && *ec)
return static_cast< uintmax_t >(-1);
@@ -936,7 +1134,15 @@ uintmax_t remove_all_impl(path const& p, error_code* ec)
}
}
- count += fs::detail::remove_impl(p, type, ec);
+ count += fs::detail::remove_impl
+ (
+ p,
+ type,
+ ec
+#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ , basedir_fd
+#endif
+ );
if (ec && *ec)
return static_cast< uintmax_t >(-1);
@@ -1088,6 +1294,7 @@ SetFileInformationByHandle_t* set_file_information_by_handle_api = NULL;
GetFileInformationByHandleEx_t* get_file_information_by_handle_ex_api = NULL;
#if !defined(UNDER_CE)
+NtCreateFile_t* nt_create_file_api = NULL;
NtQueryDirectoryFile_t* nt_query_directory_file_api = NULL;
#endif // !defined(UNDER_CE)
@@ -1129,6 +1336,7 @@ BOOST_FILESYSTEM_INIT_FUNC init_winapi_func_ptrs()
h = boost::winapi::GetModuleHandleW(L"ntdll.dll");
if (BOOST_LIKELY(!!h))
{
+ filesystem::detail::atomic_store_relaxed(nt_create_file_api, (NtCreateFile_t*)boost::winapi::get_proc_address(h, "NtCreateFile"));
filesystem::detail::atomic_store_relaxed(nt_query_directory_file_api, (NtQueryDirectoryFile_t*)boost::winapi::get_proc_address(h, "NtQueryDirectoryFile"));
}
@@ -1235,6 +1443,74 @@ inline void to_FILETIME(std::time_t t, FILETIME& ft) BOOST_NOEXCEPT
} // unnamed namespace
+#if !defined(UNDER_CE)
+
+//! The flag indicates whether OBJ_DONT_REPARSE flag is not supported by the kernel
+static bool g_no_obj_dont_reparse = false;
+
+//! Creates a file handle for a file relative to a previously opened base directory. The file path must be relative and in preferred format.
+boost::winapi::NTSTATUS_ nt_create_file_handle_at(HANDLE& out, HANDLE basedir_handle, boost::filesystem::path const& p, ULONG FileAttributes, ACCESS_MASK DesiredAccess, ULONG ShareMode, ULONG CreateDisposition, ULONG CreateOptions)
+{
+ NtCreateFile_t* nt_create_file = filesystem::detail::atomic_load_relaxed(nt_create_file_api);
+ if (BOOST_UNLIKELY(!nt_create_file))
+ return STATUS_NOT_IMPLEMENTED;
+
+ unicode_string obj_name = {};
+ obj_name.Buffer = const_cast< wchar_t* >(p.c_str());
+ obj_name.Length = obj_name.MaximumLength = static_cast< USHORT >(p.size() * sizeof(wchar_t));
+
+ object_attributes obj_attrs = {};
+ obj_attrs.Length = sizeof(obj_attrs);
+ obj_attrs.RootDirectory = basedir_handle;
+ obj_attrs.ObjectName = &obj_name;
+
+ obj_attrs.Attributes = OBJ_CASE_INSENSITIVE;
+ if ((CreateOptions & FILE_OPEN_REPARSE_POINT) != 0u && !filesystem::detail::atomic_load_relaxed(g_no_obj_dont_reparse))
+ obj_attrs.Attributes |= OBJ_DONT_REPARSE;
+
+ io_status_block iosb;
+ boost::winapi::NTSTATUS_ status = nt_create_file
+ (
+ &out,
+ DesiredAccess,
+ &obj_attrs,
+ &iosb,
+ NULL, // AllocationSize
+ FileAttributes,
+ ShareMode,
+ CreateDisposition,
+ CreateOptions,
+ NULL, // EaBuffer
+ 0u // EaLength
+ );
+
+ if (BOOST_UNLIKELY(status == STATUS_INVALID_PARAMETER && (obj_attrs.Attributes & OBJ_DONT_REPARSE) != 0u))
+ {
+ // OBJ_DONT_REPARSE is supported since Windows 10, retry without it
+ filesystem::detail::atomic_store_relaxed(g_no_obj_dont_reparse, true);
+ obj_attrs.Attributes &= ~static_cast< ULONG >(OBJ_DONT_REPARSE);
+
+ status = nt_create_file
+ (
+ &out,
+ DesiredAccess,
+ &obj_attrs,
+ &iosb,
+ NULL, // AllocationSize
+ FileAttributes,
+ ShareMode,
+ CreateDisposition,
+ CreateOptions,
+ NULL, // EaBuffer
+ 0u // EaLength
+ );
+ }
+
+ return status;
+}
+
+#endif // !defined(UNDER_CE)
+
bool is_reparse_point_a_symlink_ioctl(HANDLE h)
{
boost::scoped_ptr< reparse_data_buffer_with_storage > buf(new reparse_data_buffer_with_storage);
@@ -1252,7 +1528,13 @@ namespace {
inline bool is_reparse_point_a_symlink(path const& p)
{
- handle_wrapper h(create_file_handle(p, 0u, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT));
+ handle_wrapper h(create_file_handle(
+ p,
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT));
if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE))
return false;
@@ -1278,9 +1560,8 @@ inline std::size_t get_full_path_name(path const& src, std::size_t len, wchar_t*
return static_cast< std::size_t >(::GetFullPathNameW(src.c_str(), static_cast< DWORD >(len), buf, p));
}
-inline fs::file_status process_status_failure(path const& p, error_code* ec)
+inline fs::file_status process_status_failure(DWORD errval, path const& p, error_code* ec)
{
- DWORD errval = ::GetLastError();
if (ec) // always report errval, even though some
ec->assign(errval, system_category()); // errval values are not status_errors
@@ -1299,6 +1580,129 @@ inline fs::file_status process_status_failure(path const& p, error_code* ec)
return fs::file_status(fs::status_error);
}
+inline fs::file_status process_status_failure(path const& p, error_code* ec)
+{
+ return process_status_failure(::GetLastError(), p, ec);
+}
+
+//! (symlink_)status() by handle implementation
+fs::file_status status_by_handle(HANDLE h, path const& p, error_code* ec)
+{
+ fs::file_type ftype;
+ DWORD attrs;
+ GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api);
+ if (BOOST_LIKELY(get_file_information_by_handle_ex != NULL))
+ {
+ file_attribute_tag_info info;
+ BOOL res = get_file_information_by_handle_ex(h, file_attribute_tag_info_class, &info, sizeof(info));
+ if (BOOST_UNLIKELY(!res))
+ {
+ // On FAT/exFAT filesystems requesting FILE_ATTRIBUTE_TAG_INFO returns ERROR_INVALID_PARAMETER.
+ // Presumably, this is because these filesystems don't support reparse points, so ReparseTag
+ // cannot be returned. Also check ERROR_NOT_SUPPORTED for good measure. Fall back to the legacy
+ // code path in this case.
+ DWORD err = ::GetLastError();
+ if (err == ERROR_INVALID_PARAMETER || err == ERROR_NOT_SUPPORTED)
+ goto use_get_file_information_by_handle;
+
+ return process_status_failure(err, p, ec);
+ }
+
+ attrs = info.FileAttributes;
+
+ if (attrs & FILE_ATTRIBUTE_REPARSE_POINT)
+ {
+ ftype = is_reparse_point_tag_a_symlink(info.ReparseTag) ? fs::symlink_file : fs::reparse_file;
+ goto done;
+ }
+ }
+ else
+ {
+ use_get_file_information_by_handle:
+ BY_HANDLE_FILE_INFORMATION info;
+ BOOL res = ::GetFileInformationByHandle(h, &info);
+ if (BOOST_UNLIKELY(!res))
+ return process_status_failure(p, ec);
+
+ attrs = info.dwFileAttributes;
+
+ if (attrs & FILE_ATTRIBUTE_REPARSE_POINT)
+ {
+ ftype = is_reparse_point_a_symlink_ioctl(h) ? fs::symlink_file : fs::reparse_file;
+ goto done;
+ }
+ }
+
+ ftype = (attrs & FILE_ATTRIBUTE_DIRECTORY) ? fs::directory_file : fs::regular_file;
+
+done:
+ return fs::file_status(ftype, make_permissions(p, attrs));
+}
+
+//! symlink_status() implementation
+fs::file_status symlink_status_impl(path const& p, error_code* ec)
+{
+ handle_wrapper h(create_file_handle(
+ p.c_str(),
+ FILE_READ_ATTRIBUTES, // dwDesiredAccess; attributes only
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL, // lpSecurityAttributes
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT));
+
+ if (h.handle == INVALID_HANDLE_VALUE)
+ {
+ // For some system files and folders like "System Volume Information" CreateFileW fails
+ // with ERROR_ACCESS_DENIED. GetFileAttributesW succeeds for such files, so try that.
+ // Though this will only help if the file is not a reparse point (symlink or not).
+ DWORD err = ::GetLastError();
+ if (err == ERROR_ACCESS_DENIED)
+ {
+ DWORD attrs = ::GetFileAttributesW(p.c_str());
+ if (attrs != INVALID_FILE_ATTRIBUTES)
+ {
+ if ((attrs & FILE_ATTRIBUTE_REPARSE_POINT) == 0u)
+ return fs::file_status((attrs & FILE_ATTRIBUTE_DIRECTORY) ? fs::directory_file : fs::regular_file, make_permissions(p, attrs));
+ }
+ else
+ {
+ err = ::GetLastError();
+ }
+ }
+
+ return process_status_failure(err, p, ec);
+ }
+
+ return detail::status_by_handle(h.handle, p, ec);
+}
+
+//! status() implementation
+fs::file_status status_impl(path const& p, error_code* ec)
+{
+ // We should first test if the file is a symlink or a reparse point. Resolving some reparse
+ // points by opening the file may fail, and status() should return file_status(reparse_file) in this case.
+ // Which is what symlink_status() returns.
+ fs::file_status st(detail::symlink_status_impl(p, ec));
+ if (st.type() == symlink_file)
+ {
+ // Resolve the symlink
+ handle_wrapper h(create_file_handle(
+ p.c_str(),
+ FILE_READ_ATTRIBUTES, // dwDesiredAccess; attributes only
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, // lpSecurityAttributes
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS));
+
+ if (h.handle == INVALID_HANDLE_VALUE)
+ return process_status_failure(p, ec);
+
+ st = detail::status_by_handle(h.handle, p, ec);
+ }
+
+ return st;
+}
+
//! remove() implementation for Windows XP and older
bool remove_nt5_impl(path const& p, DWORD attrs, error_code* ec)
{
@@ -1354,32 +1758,19 @@ bool remove_nt5_impl(path const& p, DWORD attrs, error_code* ec)
return true;
}
-//! remove() implementation for Windows Vista and newer
-bool remove_nt6_impl(path const& p, remove_impl_type impl, error_code* ec)
+//! remove() by handle implementation for Windows Vista and newer
+DWORD remove_nt6_by_handle(HANDLE handle, remove_impl_type impl)
{
- handle_wrapper h(create_file_handle(p, DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT));
- DWORD err;
- if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE))
- {
- err = ::GetLastError();
-
- return_error:
- if (!not_found_error(err))
- emit_error(err, p, ec, "boost::filesystem::remove");
-
- return false;
- }
-
GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api);
SetFileInformationByHandle_t* set_file_information_by_handle = filesystem::detail::atomic_load_relaxed(set_file_information_by_handle_api);
+ DWORD err = 0u;
switch (impl)
{
case remove_disp_ex_flag_ignore_readonly:
{
file_disposition_info_ex info;
info.Flags = FILE_DISPOSITION_FLAG_DELETE | FILE_DISPOSITION_FLAG_POSIX_SEMANTICS | FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE;
- BOOL res = set_file_information_by_handle(h.handle, file_disposition_info_ex_class, &info, sizeof(info));
+ BOOL res = set_file_information_by_handle(handle, file_disposition_info_ex_class, &info, sizeof(info));
if (BOOST_LIKELY(!!res))
break;
@@ -1392,7 +1783,7 @@ bool remove_nt6_impl(path const& p, remove_impl_type impl, error_code* ec)
}
else
{
- goto return_error;
+ break;
}
}
BOOST_FALLTHROUGH;
@@ -1401,40 +1792,46 @@ bool remove_nt6_impl(path const& p, remove_impl_type impl, error_code* ec)
{
file_disposition_info_ex info;
info.Flags = FILE_DISPOSITION_FLAG_DELETE | FILE_DISPOSITION_FLAG_POSIX_SEMANTICS;
- BOOL res = set_file_information_by_handle(h.handle, file_disposition_info_ex_class, &info, sizeof(info));
+ BOOL res = set_file_information_by_handle(handle, file_disposition_info_ex_class, &info, sizeof(info));
if (BOOST_LIKELY(!!res))
+ {
+ err = 0u;
break;
+ }
err = ::GetLastError();
if (err == ERROR_ACCESS_DENIED)
{
// Check if the file is read-only and reset the attribute
file_basic_info basic_info;
- res = get_file_information_by_handle_ex(h.handle, file_basic_info_class, &basic_info, sizeof(basic_info));
+ res = get_file_information_by_handle_ex(handle, file_basic_info_class, &basic_info, sizeof(basic_info));
if (BOOST_UNLIKELY(!res || (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0))
- goto return_error; // return ERROR_ACCESS_DENIED
+ break; // return ERROR_ACCESS_DENIED
basic_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
- res = set_file_information_by_handle(h.handle, file_basic_info_class, &basic_info, sizeof(basic_info));
+ res = set_file_information_by_handle(handle, file_basic_info_class, &basic_info, sizeof(basic_info));
if (BOOST_UNLIKELY(!res))
{
err = ::GetLastError();
- goto return_error;
+ break;
}
// Try to set the flag again
- res = set_file_information_by_handle(h.handle, file_disposition_info_ex_class, &info, sizeof(info));
+ res = set_file_information_by_handle(handle, file_disposition_info_ex_class, &info, sizeof(info));
if (BOOST_LIKELY(!!res))
+ {
+ err = 0u;
break;
+ }
err = ::GetLastError();
// Try to restore the read-only flag
basic_info.FileAttributes |= FILE_ATTRIBUTE_READONLY;
- set_file_information_by_handle(h.handle, file_basic_info_class, &basic_info, sizeof(basic_info));
+ set_file_information_by_handle(handle, file_basic_info_class, &basic_info, sizeof(basic_info));
- goto return_error;
+ break;
}
else if (BOOST_UNLIKELY(err == ERROR_INVALID_PARAMETER || err == ERROR_INVALID_FUNCTION || err == ERROR_NOT_SUPPORTED))
{
@@ -1444,7 +1841,7 @@ bool remove_nt6_impl(path const& p, remove_impl_type impl, error_code* ec)
}
else
{
- goto return_error;
+ break;
}
}
BOOST_FALLTHROUGH;
@@ -1453,54 +1850,89 @@ bool remove_nt6_impl(path const& p, remove_impl_type impl, error_code* ec)
{
file_disposition_info info;
info.DeleteFile = true;
- BOOL res = set_file_information_by_handle(h.handle, file_disposition_info_class, &info, sizeof(info));
+ BOOL res = set_file_information_by_handle(handle, file_disposition_info_class, &info, sizeof(info));
if (BOOST_LIKELY(!!res))
+ {
+ err = 0u;
break;
+ }
err = ::GetLastError();
if (err == ERROR_ACCESS_DENIED)
{
// Check if the file is read-only and reset the attribute
file_basic_info basic_info;
- res = get_file_information_by_handle_ex(h.handle, file_basic_info_class, &basic_info, sizeof(basic_info));
+ res = get_file_information_by_handle_ex(handle, file_basic_info_class, &basic_info, sizeof(basic_info));
if (BOOST_UNLIKELY(!res || (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0))
- goto return_error; // return ERROR_ACCESS_DENIED
+ break; // return ERROR_ACCESS_DENIED
basic_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
- res = set_file_information_by_handle(h.handle, file_basic_info_class, &basic_info, sizeof(basic_info));
+ res = set_file_information_by_handle(handle, file_basic_info_class, &basic_info, sizeof(basic_info));
if (BOOST_UNLIKELY(!res))
{
err = ::GetLastError();
- goto return_error;
+ break;
}
// Try to set the flag again
- res = set_file_information_by_handle(h.handle, file_disposition_info_class, &info, sizeof(info));
+ res = set_file_information_by_handle(handle, file_disposition_info_class, &info, sizeof(info));
if (BOOST_LIKELY(!!res))
+ {
+ err = 0u;
break;
+ }
err = ::GetLastError();
// Try to restore the read-only flag
basic_info.FileAttributes |= FILE_ATTRIBUTE_READONLY;
- set_file_information_by_handle(h.handle, file_basic_info_class, &basic_info, sizeof(basic_info));
+ set_file_information_by_handle(handle, file_basic_info_class, &basic_info, sizeof(basic_info));
}
- goto return_error;
+ break;
}
}
+ return err;
+}
+
+//! remove() implementation for Windows Vista and newer
+inline bool remove_nt6_impl(path const& p, remove_impl_type impl, error_code* ec)
+{
+ handle_wrapper h(create_file_handle(
+ p,
+ DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT));
+ DWORD err = 0u;
+ if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE))
+ {
+ err = ::GetLastError();
+
+ return_error:
+ if (!not_found_error(err))
+ emit_error(err, p, ec, "boost::filesystem::remove");
+
+ return false;
+ }
+
+ err = fs::detail::remove_nt6_by_handle(h.handle, impl);
+ if (BOOST_UNLIKELY(err != 0u))
+ goto return_error;
+
return true;
}
//! remove() implementation
inline bool remove_impl(path const& p, error_code* ec)
{
- remove_impl_type impl = filesystem::detail::atomic_load_relaxed(g_remove_impl_type);
+ remove_impl_type impl = fs::detail::atomic_load_relaxed(g_remove_impl_type);
if (BOOST_LIKELY(impl != remove_nt5))
{
- return remove_nt6_impl(p, impl, ec);
+ return fs::detail::remove_nt6_impl(p, impl, ec);
}
else
{
@@ -1514,14 +1946,131 @@ inline bool remove_impl(path const& p, error_code* ec)
return false;
}
- return remove_nt5_impl(p, attrs, ec);
+ return fs::detail::remove_nt5_impl(p, attrs, ec);
}
}
-//! remove_all() implementation
-uintmax_t remove_all_impl(path const& p, error_code* ec)
+#if !defined(UNDER_CE)
+
+//! remove_all() by handle implementation for Windows Vista and newer
+uintmax_t remove_all_nt6_by_handle(HANDLE h, path const& p, error_code* ec)
+{
+ error_code local_ec;
+ fs::file_status st(fs::detail::status_by_handle(h, p, &local_ec));
+ if (BOOST_UNLIKELY(st.type() == fs::status_error))
+ {
+ if (!ec)
+ BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all", p, local_ec));
+
+ *ec = local_ec;
+ return static_cast< uintmax_t >(-1);
+ }
+
+ uintmax_t count = 0u;
+ if (st.type() == fs::directory_file)
+ {
+ local_ec.clear();
+
+ fs::directory_iterator itr;
+ directory_iterator_params params;
+ params.use_handle = h;
+ params.close_handle = false; // the caller will close the handle
+ fs::detail::directory_iterator_construct(itr, p, static_cast< unsigned int >(directory_options::_detail_no_follow), &params, &local_ec);
+ if (BOOST_UNLIKELY(!!local_ec))
+ {
+ if (!ec)
+ BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all", p, local_ec));
+
+ *ec = local_ec;
+ return static_cast< uintmax_t >(-1);
+ }
+
+ NtCreateFile_t* nt_create_file = filesystem::detail::atomic_load_relaxed(nt_create_file_api);
+ const fs::directory_iterator end_dit;
+ while (itr != end_dit)
+ {
+ fs::path nested_path(itr->path());
+ handle_wrapper hh;
+ if (BOOST_LIKELY(nt_create_file != NULL))
+ {
+ // Note: WinAPI methods like CreateFileW implicitly request SYNCHRONIZE access but NtCreateFile doesn't.
+ // Without SYNCHRONIZE access querying file attributes via GetFileInformationByHandleEx fails with ERROR_ACCESS_DENIED.
+ boost::winapi::NTSTATUS_ status = nt_create_file_handle_at
+ (
+ hh.handle,
+ h,
+ nested_path.filename(),
+ 0u, // FileAttributes
+ FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ FILE_OPEN,
+ FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT
+ );
+
+ if (!NT_SUCCESS(status))
+ {
+ if (status == STATUS_NO_SUCH_FILE ||
+ status == STATUS_OBJECT_NAME_NOT_FOUND ||
+ status == STATUS_OBJECT_PATH_NOT_FOUND ||
+ status == STATUS_BAD_NETWORK_PATH ||
+ status == STATUS_BAD_NETWORK_NAME)
+ {
+ goto next_entry;
+ }
+
+ DWORD err = translate_ntstatus(status);
+ emit_error(err, nested_path, ec, "boost::filesystem::remove_all");
+ return static_cast< uintmax_t >(-1);
+ }
+ }
+ else
+ {
+ hh.handle = create_file_handle(
+ nested_path,
+ FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT);
+
+ if (BOOST_UNLIKELY(hh.handle == INVALID_HANDLE_VALUE))
+ {
+ DWORD err = ::GetLastError();
+ if (not_found_error(err))
+ goto next_entry;
+
+ emit_error(err, nested_path, ec, "boost::filesystem::remove_all");
+ return static_cast< uintmax_t >(-1);
+ }
+ }
+
+ count += fs::detail::remove_all_nt6_by_handle(hh.handle, nested_path, ec);
+ if (ec && *ec)
+ return static_cast< uintmax_t >(-1);
+
+ next_entry:
+ fs::detail::directory_iterator_increment(itr, ec);
+ if (ec && *ec)
+ return static_cast< uintmax_t >(-1);
+ }
+ }
+
+ DWORD err = fs::detail::remove_nt6_by_handle(h, fs::detail::atomic_load_relaxed(g_remove_impl_type));
+ if (BOOST_UNLIKELY(err != 0u))
+ {
+ emit_error(err, p, ec, "boost::filesystem::remove_all");
+ return static_cast< uintmax_t >(-1);
+ }
+
+ ++count;
+ return count;
+}
+
+#endif // !defined(UNDER_CE)
+
+//! remove_all() implementation for Windows XP and older
+uintmax_t remove_all_nt5_impl(path const& p, error_code* ec)
{
- remove_impl_type impl = filesystem::detail::atomic_load_relaxed(g_remove_impl_type);
error_code dit_create_ec;
for (unsigned int attempt = 0u; attempt < remove_all_directory_replaced_retry_count; ++attempt)
{
@@ -1542,7 +2091,7 @@ uintmax_t remove_all_impl(path const& p, error_code* ec)
if (recurse)
{
fs::directory_iterator itr;
- fs::detail::directory_iterator_construct(itr, p, static_cast< unsigned int >(directory_options::_detail_no_follow), &dit_create_ec);
+ fs::detail::directory_iterator_construct(itr, p, static_cast< unsigned int >(directory_options::_detail_no_follow), NULL, &dit_create_ec);
if (BOOST_UNLIKELY(!!dit_create_ec))
{
if (dit_create_ec == make_error_condition(system::errc::not_a_directory) ||
@@ -1561,7 +2110,7 @@ uintmax_t remove_all_impl(path const& p, error_code* ec)
const fs::directory_iterator end_dit;
while (itr != end_dit)
{
- count += remove_all_impl(itr->path(), ec);
+ count += fs::detail::remove_all_nt5_impl(itr->path(), ec);
if (ec && *ec)
return static_cast< uintmax_t >(-1);
@@ -1571,11 +2120,7 @@ uintmax_t remove_all_impl(path const& p, error_code* ec)
}
}
- bool removed;
- if (BOOST_LIKELY(impl != remove_nt5))
- removed = remove_nt6_impl(p, impl, ec);
- else
- removed = remove_nt5_impl(p, attrs, ec);
+ bool removed = fs::detail::remove_nt5_impl(p, attrs, ec);
if (ec && *ec)
return static_cast< uintmax_t >(-1);
@@ -1590,6 +2135,38 @@ uintmax_t remove_all_impl(path const& p, error_code* ec)
return static_cast< uintmax_t >(-1);
}
+//! remove_all() implementation
+inline uintmax_t remove_all_impl(path const& p, error_code* ec)
+{
+#if !defined(UNDER_CE)
+ remove_impl_type impl = fs::detail::atomic_load_relaxed(g_remove_impl_type);
+ if (BOOST_LIKELY(impl != remove_nt5))
+ {
+ handle_wrapper h(create_file_handle(
+ p,
+ FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT));
+
+ if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE))
+ {
+ DWORD err = ::GetLastError();
+ if (not_found_error(err))
+ return 0u;
+
+ emit_error(err, p, ec, "boost::filesystem::remove_all");
+ return static_cast< uintmax_t >(-1);
+ }
+
+ return fs::detail::remove_all_nt6_by_handle(h.handle, p, ec);
+ }
+#endif // !defined(UNDER_CE)
+
+ return fs::detail::remove_all_nt5_impl(p, ec);
+}
+
inline BOOL resize_file_impl(const wchar_t* p, uintmax_t size)
{
handle_wrapper h(CreateFileW(p, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
@@ -1836,7 +2413,7 @@ path canonical(path const& p, path const& base, system::error_code* ec)
}
system::error_code local_ec;
- file_status st(detail::status(source, &local_ec));
+ file_status st(detail::status_impl(source, &local_ec));
if (st.type() == fs::file_not_found)
{
@@ -1890,7 +2467,7 @@ path canonical(path const& p, path const& base, system::error_code* ec)
if (!result.is_absolute())
continue;
- st = detail::symlink_status(result, ec);
+ st = detail::symlink_status_impl(result, ec);
if (ec && *ec)
goto return_empty_path;
@@ -1964,16 +2541,19 @@ void copy(path const& from, path const& to, unsigned int options, system::error_
((options & static_cast< unsigned int >(copy_options::create_symlinks)) != 0u) +
((options & static_cast< unsigned int >(copy_options::create_hard_links)) != 0u)) <= 1);
+ if (ec)
+ ec->clear();
+
file_status from_stat;
if ((options & (static_cast< unsigned int >(copy_options::copy_symlinks) |
static_cast< unsigned int >(copy_options::skip_symlinks) |
static_cast< unsigned int >(copy_options::create_symlinks))) != 0u)
{
- from_stat = detail::symlink_status(from, ec);
+ from_stat = detail::symlink_status_impl(from, ec);
}
else
{
- from_stat = detail::status(from, ec);
+ from_stat = detail::status_impl(from, ec);
}
if (ec && *ec)
@@ -2044,11 +2624,11 @@ void copy(path const& from, path const& to, unsigned int options, system::error_
if ((options & (static_cast< unsigned int >(copy_options::skip_symlinks) |
static_cast< unsigned int >(copy_options::create_symlinks))) != 0u)
{
- to_stat = detail::symlink_status(to, &local_ec);
+ to_stat = detail::symlink_status_impl(to, &local_ec);
}
else
{
- to_stat = detail::status(to, &local_ec);
+ to_stat = detail::status_impl(to, &local_ec);
}
// Note: local_ec may be set by (symlink_)status() even in some non-fatal situations, e.g. when the file does not exist.
@@ -2082,11 +2662,11 @@ void copy(path const& from, path const& to, unsigned int options, system::error_
if ((options & (static_cast< unsigned int >(copy_options::skip_symlinks) |
static_cast< unsigned int >(copy_options::create_symlinks))) != 0u)
{
- to_stat = detail::symlink_status(to, &local_ec);
+ to_stat = detail::symlink_status_impl(to, &local_ec);
}
else
{
- to_stat = detail::status(to, &local_ec);
+ to_stat = detail::status_impl(to, &local_ec);
}
// Note: ec may be set by (symlink_)status() even in some non-fatal situations, e.g. when the file does not exist.
@@ -2109,7 +2689,7 @@ void copy(path const& from, path const& to, unsigned int options, system::error_
if ((options & static_cast< unsigned int >(copy_options::recursive)) != 0u || options == 0u)
{
fs::directory_iterator itr;
- detail::directory_iterator_construct(itr, from, static_cast< unsigned int >(directory_options::none), ec);
+ detail::directory_iterator_construct(itr, from, static_cast< unsigned int >(directory_options::none), NULL, ec);
if (ec && *ec)
return;
@@ -2205,7 +2785,7 @@ bool copy_file(path const& from, path const& to, unsigned int options, error_cod
}
mode_t to_mode = from_mode;
-#if !defined(__wasm)
+#if !defined(BOOST_FILESYSTEM_USE_WASI)
// Enable writing for the newly created files. Having write permission set is important e.g. for NFS,
// which checks the file permission on the server, even if the client's file descriptor supports writing.
to_mode |= S_IWUSR;
@@ -2324,7 +2904,7 @@ bool copy_file(path const& from, path const& to, unsigned int options, error_cod
if (BOOST_UNLIKELY(err != 0))
goto fail; // err already contains the error code
-#if !defined(__wasm)
+#if !defined(BOOST_FILESYSTEM_USE_WASI)
// If we created a new file with an explicitly added S_IWUSR permission,
// we may need to update its mode bits to match the source file.
if (to_mode != from_mode)
@@ -2373,7 +2953,7 @@ bool copy_file(path const& from, path const& to, unsigned int options, error_cod
// Create handle_wrappers here so that CloseHandle calls don't clobber error code returned by GetLastError
handle_wrapper hw_from, hw_to;
- hw_from.handle = create_file_handle(from.c_str(), 0u, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS);
+ hw_from.handle = create_file_handle(from.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS);
FILETIME lwt_from;
if (hw_from.handle == INVALID_HANDLE_VALUE)
@@ -2384,15 +2964,15 @@ bool copy_file(path const& from, path const& to, unsigned int options, error_cod
return false;
}
- if (!::GetFileTime(hw_from.handle, 0, 0, &lwt_from))
+ if (!::GetFileTime(hw_from.handle, NULL, NULL, &lwt_from))
goto fail_last_error;
- hw_to.handle = create_file_handle(to.c_str(), 0u, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS);
+ hw_to.handle = create_file_handle(to.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS);
if (hw_to.handle != INVALID_HANDLE_VALUE)
{
FILETIME lwt_to;
- if (!::GetFileTime(hw_to.handle, 0, 0, &lwt_to))
+ if (!::GetFileTime(hw_to.handle, NULL, NULL, &lwt_to))
goto fail_last_error;
ULONGLONG tfrom = (static_cast< ULONGLONG >(lwt_from.dwHighDateTime) << 32) | static_cast< ULONGLONG >(lwt_from.dwLowDateTime);
@@ -2512,7 +3092,7 @@ bool create_directories(path const& p, system::error_code* ec)
{
if (!fname.empty() && fname != dot_p && fname != dot_dot_p)
{
- file_status existing_status = detail::status(parent, &local_ec);
+ file_status existing_status = detail::status_impl(parent, &local_ec);
if (existing_status.type() == directory_file)
{
@@ -2760,7 +3340,7 @@ void create_symlink(path const& to, path const& from, error_code* ec)
BOOST_FILESYSTEM_DECL
path current_path(error_code* ec)
{
-#if defined(UNDER_CE) || defined(__wasm)
+#if defined(UNDER_CE) || defined(BOOST_FILESYSTEM_USE_WASI)
// Windows CE has no current directory, so everything's relative to the root of the directory tree.
// WASI also does not support current path.
emit_error(BOOST_ERROR_NOT_SUPPORTED, ec, "boost::filesystem::current_path");
@@ -2830,7 +3410,7 @@ path current_path(error_code* ec)
BOOST_FILESYSTEM_DECL
void current_path(path const& p, system::error_code* ec)
{
-#if defined(UNDER_CE) || defined(__wasm)
+#if defined(UNDER_CE) || defined(BOOST_FILESYSTEM_USE_WASI)
emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::current_path");
#else
error(!BOOST_SET_CURRENT_DIRECTORY(p.c_str()) ? BOOST_ERRNO : 0, p, ec, "boost::filesystem::current_path");
@@ -2894,23 +3474,21 @@ bool equivalent(path const& p1, path const& p2, system::error_code* ec)
// been retrieved.
// p2 is done first, so any error reported is for p1
- handle_wrapper h2(
- create_file_handle(
- p2.c_str(),
- 0u,
- FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS));
-
- handle_wrapper h1(
- create_file_handle(
- p1.c_str(),
- 0u,
- FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS));
+ handle_wrapper h2(create_file_handle(
+ p2.c_str(),
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS));
+
+ handle_wrapper h1(create_file_handle(
+ p1.c_str(),
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS));
if (BOOST_UNLIKELY(h1.handle == INVALID_HANDLE_VALUE || h2.handle == INVALID_HANDLE_VALUE))
{
@@ -3044,8 +3622,13 @@ uintmax_t hard_link_count(path const& p, system::error_code* ec)
#else // defined(BOOST_POSIX_API)
- handle_wrapper h(
- create_file_handle(p.c_str(), 0u, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS));
+ handle_wrapper h(create_file_handle(
+ p.c_str(),
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS));
if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE))
{
@@ -3166,8 +3749,13 @@ std::time_t creation_time(path const& p, system::error_code* ec)
#else // defined(BOOST_POSIX_API)
- handle_wrapper hw(
- create_file_handle(p.c_str(), 0u, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS));
+ handle_wrapper hw(create_file_handle(
+ p.c_str(),
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS));
if (BOOST_UNLIKELY(hw.handle == INVALID_HANDLE_VALUE))
{
@@ -3219,8 +3807,13 @@ std::time_t last_write_time(path const& p, system::error_code* ec)
#else // defined(BOOST_POSIX_API)
- handle_wrapper hw(
- create_file_handle(p.c_str(), 0u, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS));
+ handle_wrapper hw(create_file_handle(
+ p.c_str(),
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS));
if (BOOST_UNLIKELY(hw.handle == INVALID_HANDLE_VALUE))
{
@@ -3247,7 +3840,7 @@ void last_write_time(path const& p, const std::time_t new_time, system::error_co
#if defined(BOOST_POSIX_API)
-#if _POSIX_C_SOURCE >= 200809L
+#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
struct timespec times[2] = {};
@@ -3262,7 +3855,7 @@ void last_write_time(path const& p, const std::time_t new_time, system::error_co
return;
}
-#else // _POSIX_C_SOURCE >= 200809L
+#else // defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
struct ::stat st;
if (BOOST_UNLIKELY(::stat(p.c_str(), &st) < 0))
@@ -3272,17 +3865,22 @@ void last_write_time(path const& p, const std::time_t new_time, system::error_co
}
::utimbuf buf;
- buf.actime = st.st_atime; // utime()updates access time too:-(
+ buf.actime = st.st_atime; // utime() updates access time too :-(
buf.modtime = new_time;
if (BOOST_UNLIKELY(::utime(p.c_str(), &buf) < 0))
emit_error(BOOST_ERRNO, p, ec, "boost::filesystem::last_write_time");
-#endif // _POSIX_C_SOURCE >= 200809L
+#endif // defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
#else // defined(BOOST_POSIX_API)
- handle_wrapper hw(
- create_file_handle(p.c_str(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS));
+ handle_wrapper hw(create_file_handle(
+ p.c_str(),
+ FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS));
if (BOOST_UNLIKELY(hw.handle == INVALID_HANDLE_VALUE))
{
@@ -3294,7 +3892,7 @@ void last_write_time(path const& p, const std::time_t new_time, system::error_co
FILETIME lwt;
to_FILETIME(new_time, lwt);
- if (BOOST_UNLIKELY(!::SetFileTime(hw.handle, 0, 0, &lwt)))
+ if (BOOST_UNLIKELY(!::SetFileTime(hw.handle, NULL, NULL, &lwt)))
goto fail;
#endif // defined(BOOST_POSIX_API)
@@ -3316,11 +3914,11 @@ void permissions(path const& p, perms prms, system::error_code* ec)
if ((prms & add_perms) && (prms & remove_perms)) // precondition failed
return;
-#if defined(__wasm)
+#if defined(BOOST_FILESYSTEM_USE_WASI)
emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::permissions");
#elif defined(BOOST_POSIX_API)
error_code local_ec;
- file_status current_status((prms & symlink_perms) ? fs::symlink_status(p, local_ec) : fs::status(p, local_ec));
+ file_status current_status((prms & symlink_perms) ? detail::symlink_status_impl(p, &local_ec) : detail::status_impl(p, &local_ec));
if (local_ec)
{
if (!ec)
@@ -3346,11 +3944,12 @@ void permissions(path const& p, perms prms, system::error_code* ec)
// "http://man7.org/linux/man-pages/man7/symlink.7.html"
// - See the fchmodat() Linux man page:
// "http://man7.org/linux/man-pages/man2/fchmodat.2.html"
-#if defined(AT_FDCWD) && defined(AT_SYMLINK_NOFOLLOW) && \
+#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS) && \
!(defined(__SUNPRO_CC) || defined(__sun) || defined(sun)) && \
!(defined(linux) || defined(__linux) || defined(__linux__)) && \
!(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101000) && \
!(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 80000) && \
+ !(defined(__rtems__)) && \
!(defined(__QNX__) && (_NTO_VERSION <= 700))
if (::fchmodat(AT_FDCWD, p.c_str(), mode_cast(prms), !(prms & symlink_perms) ? 0 : AT_SYMLINK_NOFOLLOW))
#else // fallback if fchmodat() not supported
@@ -3445,8 +4044,13 @@ path read_symlink(path const& p, system::error_code* ec)
#else
- handle_wrapper h(
- create_file_handle(p.c_str(), 0u, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT));
+ handle_wrapper h(create_file_handle(
+ p.c_str(),
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT));
DWORD error;
if (BOOST_UNLIKELY(h.handle == INVALID_HANDLE_VALUE))
@@ -3460,7 +4064,7 @@ path read_symlink(path const& p, system::error_code* ec)
boost::scoped_ptr< reparse_data_buffer_with_storage > buf(new reparse_data_buffer_with_storage);
DWORD sz = 0u;
- if (BOOST_UNLIKELY(!::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT, 0, 0, buf.get(), sizeof(*buf), &sz, 0)))
+ if (BOOST_UNLIKELY(!::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT, NULL, 0, buf.get(), sizeof(*buf), &sz, NULL)))
{
error = ::GetLastError();
goto return_error;
@@ -3575,7 +4179,7 @@ space_info space(path const& p, error_code* ec)
if (ec)
ec->clear();
-#if defined(__wasm)
+#if defined(BOOST_FILESYSTEM_USE_WASI)
emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::space");
@@ -3594,7 +4198,7 @@ space_info space(path const& p, error_code* ec)
// GetDiskFreeSpaceExW requires a directory path, which is unlike statvfs, which accepts any file.
// To work around this, test if the path refers to a directory and use the parent directory if not.
error_code local_ec;
- file_status status = detail::status(p, &local_ec);
+ file_status status = detail::status_impl(p, &local_ec);
if (status.type() == fs::status_error || status.type() == fs::file_not_found)
{
fail_local_ec:
@@ -3611,7 +4215,7 @@ space_info space(path const& p, error_code* ec)
if (ec && *ec)
return info;
- status = detail::symlink_status(p, &local_ec);
+ status = detail::symlink_status_impl(p, &local_ec);
if (status.type() == fs::status_error)
goto fail_local_ec;
if (is_symlink(status))
@@ -3654,106 +4258,7 @@ file_status status(path const& p, error_code* ec)
if (ec)
ec->clear();
-#if defined(BOOST_POSIX_API)
-
-#if defined(BOOST_FILESYSTEM_USE_STATX)
- struct ::statx path_stat;
- int err = invoke_statx(AT_FDCWD, p.c_str(), AT_NO_AUTOMOUNT, STATX_TYPE | STATX_MODE, &path_stat);
-#else
- struct ::stat path_stat;
- int err = ::stat(p.c_str(), &path_stat);
-#endif
-
- if (err != 0)
- {
- err = errno;
- if (ec) // always report errno, even though some
- ec->assign(err, system_category()); // errno values are not status_errors
-
- if (not_found_error(err))
- return fs::file_status(fs::file_not_found, fs::no_perms);
-
- if (!ec)
- BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status", p, error_code(err, system_category())));
-
- return fs::file_status(fs::status_error);
- }
-
-#if defined(BOOST_FILESYSTEM_USE_STATX)
- if (BOOST_UNLIKELY((path_stat.stx_mask & (STATX_TYPE | STATX_MODE)) != (STATX_TYPE | STATX_MODE)))
- {
- emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::status");
- return fs::file_status(fs::status_error);
- }
-#endif
-
- const mode_t mode = get_mode(path_stat);
- if (S_ISDIR(mode))
- return fs::file_status(fs::directory_file, static_cast< perms >(mode) & fs::perms_mask);
- if (S_ISREG(mode))
- return fs::file_status(fs::regular_file, static_cast< perms >(mode) & fs::perms_mask);
- if (S_ISBLK(mode))
- return fs::file_status(fs::block_file, static_cast< perms >(mode) & fs::perms_mask);
- if (S_ISCHR(mode))
- return fs::file_status(fs::character_file, static_cast< perms >(mode) & fs::perms_mask);
- if (S_ISFIFO(mode))
- return fs::file_status(fs::fifo_file, static_cast< perms >(mode) & fs::perms_mask);
- if (S_ISSOCK(mode))
- return fs::file_status(fs::socket_file, static_cast< perms >(mode) & fs::perms_mask);
- return fs::file_status(fs::type_unknown);
-
-#else // defined(BOOST_POSIX_API)
-
- // We should first test if the file is a symlink or a reparse point. Resolving some reparse
- // points by opening the file may fail, and status() should return file_status(reparse_file) in this case.
- // Which is what symlink_status() returns.
- fs::file_status st(detail::symlink_status(p, ec));
- if (st.type() == symlink_file)
- {
- // Resolve the symlink
- handle_wrapper h(
- create_file_handle(
- p.c_str(),
- 0u, // dwDesiredAccess; attributes only
- FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, // lpSecurityAttributes
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS));
-
- if (h.handle == INVALID_HANDLE_VALUE)
- {
- return_status_failure:
- return process_status_failure(p, ec);
- }
-
- DWORD attrs;
- GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api);
- if (BOOST_LIKELY(get_file_information_by_handle_ex != NULL))
- {
- file_attribute_tag_info info;
- BOOL res = get_file_information_by_handle_ex(h.handle, file_attribute_tag_info_class, &info, sizeof(info));
- if (BOOST_UNLIKELY(!res))
- goto return_status_failure;
-
- attrs = info.FileAttributes;
- }
- else
- {
- BY_HANDLE_FILE_INFORMATION info;
- BOOL res = ::GetFileInformationByHandle(h.handle, &info);
- if (BOOST_UNLIKELY(!res))
- goto return_status_failure;
-
- attrs = info.dwFileAttributes;
- }
-
- st.permissions(make_permissions(p, attrs));
- st.type((attrs & FILE_ATTRIBUTE_DIRECTORY) ? fs::directory_file : fs::regular_file);
- }
-
- return st;
-
-#endif // defined(BOOST_POSIX_API)
+ return detail::status_impl(p, ec);
}
BOOST_FILESYSTEM_DECL
@@ -3762,106 +4267,7 @@ file_status symlink_status(path const& p, error_code* ec)
if (ec)
ec->clear();
-#if defined(BOOST_POSIX_API)
-
-#if defined(BOOST_FILESYSTEM_USE_STATX)
- struct ::statx path_stat;
- int err = invoke_statx(AT_FDCWD, p.c_str(), AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT, STATX_TYPE | STATX_MODE, &path_stat);
-#else
- struct ::stat path_stat;
- int err = ::lstat(p.c_str(), &path_stat);
-#endif
-
- if (err != 0)
- {
- err = errno;
- if (ec) // always report errno, even though some
- ec->assign(err, system_category()); // errno values are not status_errors
-
- if (not_found_error(err)) // these are not errors
- return fs::file_status(fs::file_not_found, fs::no_perms);
-
- if (!ec)
- BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::symlink_status", p, error_code(err, system_category())));
-
- return fs::file_status(fs::status_error);
- }
-
-#if defined(BOOST_FILESYSTEM_USE_STATX)
- if (BOOST_UNLIKELY((path_stat.stx_mask & (STATX_TYPE | STATX_MODE)) != (STATX_TYPE | STATX_MODE)))
- {
- emit_error(BOOST_ERROR_NOT_SUPPORTED, p, ec, "boost::filesystem::symlink_status");
- return fs::file_status(fs::status_error);
- }
-#endif
-
- const mode_t mode = get_mode(path_stat);
- if (S_ISREG(mode))
- return fs::file_status(fs::regular_file, static_cast< perms >(mode) & fs::perms_mask);
- if (S_ISDIR(mode))
- return fs::file_status(fs::directory_file, static_cast< perms >(mode) & fs::perms_mask);
- if (S_ISLNK(mode))
- return fs::file_status(fs::symlink_file, static_cast< perms >(mode) & fs::perms_mask);
- if (S_ISBLK(mode))
- return fs::file_status(fs::block_file, static_cast< perms >(mode) & fs::perms_mask);
- if (S_ISCHR(mode))
- return fs::file_status(fs::character_file, static_cast< perms >(mode) & fs::perms_mask);
- if (S_ISFIFO(mode))
- return fs::file_status(fs::fifo_file, static_cast< perms >(mode) & fs::perms_mask);
- if (S_ISSOCK(mode))
- return fs::file_status(fs::socket_file, static_cast< perms >(mode) & fs::perms_mask);
- return fs::file_status(fs::type_unknown);
-
-#else // defined(BOOST_POSIX_API)
-
- handle_wrapper h(
- create_file_handle(
- p.c_str(),
- 0u, // dwDesiredAccess; attributes only
- FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, // lpSecurityAttributes
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT));
-
- if (h.handle == INVALID_HANDLE_VALUE)
- {
- return_status_failure:
- return process_status_failure(p, ec);
- }
-
- DWORD attrs;
- fs::perms permissions;
- GetFileInformationByHandleEx_t* get_file_information_by_handle_ex = filesystem::detail::atomic_load_relaxed(get_file_information_by_handle_ex_api);
- if (BOOST_LIKELY(get_file_information_by_handle_ex != NULL))
- {
- file_attribute_tag_info info;
- BOOL res = get_file_information_by_handle_ex(h.handle, file_attribute_tag_info_class, &info, sizeof(info));
- if (BOOST_UNLIKELY(!res))
- goto return_status_failure;
-
- attrs = info.FileAttributes;
- permissions = make_permissions(p, attrs);
-
- if (attrs & FILE_ATTRIBUTE_REPARSE_POINT)
- return is_reparse_point_tag_a_symlink(info.ReparseTag) ? fs::file_status(fs::symlink_file, permissions) : fs::file_status(fs::reparse_file, permissions);
- }
- else
- {
- BY_HANDLE_FILE_INFORMATION info;
- BOOL res = ::GetFileInformationByHandle(h.handle, &info);
- if (BOOST_UNLIKELY(!res))
- goto return_status_failure;
-
- attrs = info.dwFileAttributes;
- permissions = make_permissions(p, attrs);
-
- if (attrs & FILE_ATTRIBUTE_REPARSE_POINT)
- return is_reparse_point_a_symlink_ioctl(h.handle) ? fs::file_status(fs::symlink_file, permissions) : fs::file_status(fs::reparse_file, permissions);
- }
-
- return (attrs & FILE_ATTRIBUTE_DIRECTORY) ? fs::file_status(fs::directory_file, permissions) : fs::file_status(fs::regular_file, permissions);
-
-#endif // defined(BOOST_POSIX_API)
+ return detail::symlink_status_impl(p, ec);
}
// contributed by Jeff Flinn
@@ -3893,7 +4299,7 @@ path temp_directory_path(system::error_code* ec)
return p;
}
- file_status status = detail::status(p, ec);
+ file_status status = detail::status_impl(p, ec);
if (BOOST_UNLIKELY(ec && *ec))
return path();
if (BOOST_UNLIKELY(!is_directory(status)))
@@ -3969,7 +4375,7 @@ path temp_directory_path(system::error_code* ec)
path p(buf.get());
p.remove_trailing_separator();
- file_status status = detail::status(p, ec);
+ file_status status = detail::status_impl(p, ec);
if (ec && *ec)
return path();
if (!is_directory(status))
@@ -4028,7 +4434,7 @@ path weakly_canonical(path const& p, path const& base, system::error_code* ec)
path head(p);
for (; !head.empty(); --itr)
{
- file_status head_status = detail::status(head, &local_ec);
+ file_status head_status = detail::status_impl(head, &local_ec);
if (BOOST_UNLIKELY(head_status.type() == fs::status_error))
{
if (!ec)
@@ -4069,7 +4475,7 @@ path weakly_canonical(path const& p, path const& base, system::error_code* ec)
head /= p_elem;
}
- file_status head_status = detail::status(head, &local_ec);
+ file_status head_status = detail::status_impl(head, &local_ec);
if (BOOST_UNLIKELY(head_status.type() == fs::status_error))
{
if (!ec)
@@ -4138,3 +4544,5 @@ path weakly_canonical(path const& p, path const& base, system::error_code* ec)
} // namespace detail
} // namespace filesystem
} // namespace boost
+
+#include <boost/filesystem/detail/footer.hpp>
diff --git a/contrib/restricted/boost/filesystem/src/path.cpp b/contrib/restricted/boost/filesystem/src/path.cpp
index f6cb3ba9a16..27b32e57c52 100644
--- a/contrib/restricted/boost/filesystem/src/path.cpp
+++ b/contrib/restricted/boost/filesystem/src/path.cpp
@@ -40,6 +40,8 @@
#include "atomic_tools.hpp"
#include "private_config.hpp"
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
+
namespace fs = boost::filesystem;
using boost::filesystem::path;
@@ -1678,3 +1680,5 @@ BOOST_FILESYSTEM_DECL path const& dot_dot_path()
} // namespace detail
} // namespace filesystem
} // namespace boost
+
+#include <boost/filesystem/detail/footer.hpp>
diff --git a/contrib/restricted/boost/filesystem/src/path_traits.cpp b/contrib/restricted/boost/filesystem/src/path_traits.cpp
index d882ad89a08..aa4b8815f7b 100644
--- a/contrib/restricted/boost/filesystem/src/path_traits.cpp
+++ b/contrib/restricted/boost/filesystem/src/path_traits.cpp
@@ -22,6 +22,8 @@
#include <cwchar> // for wcslen
#include <cstddef>
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
+
namespace pt = boost::filesystem::path_traits;
namespace fs = boost::filesystem;
namespace bs = boost::system;
@@ -195,3 +197,5 @@ void convert(const wchar_t* from,
} // namespace path_traits
} // namespace filesystem
} // namespace boost
+
+#include <boost/filesystem/detail/footer.hpp>
diff --git a/contrib/restricted/boost/filesystem/src/portability.cpp b/contrib/restricted/boost/filesystem/src/portability.cpp
index 43e63b074ec..8e0e2e5d98d 100644
--- a/contrib/restricted/boost/filesystem/src/portability.cpp
+++ b/contrib/restricted/boost/filesystem/src/portability.cpp
@@ -17,6 +17,8 @@
#include <cstring> // SGI MIPSpro compilers need this
#include <string>
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
+
namespace boost {
namespace filesystem {
@@ -77,3 +79,5 @@ BOOST_FILESYSTEM_DECL bool portable_file_name(std::string const& name)
} // namespace filesystem
} // namespace boost
+
+#include <boost/filesystem/detail/footer.hpp>
diff --git a/contrib/restricted/boost/filesystem/src/posix_tools.hpp b/contrib/restricted/boost/filesystem/src/posix_tools.hpp
index 52426d4a36a..52cd87b0a02 100644
--- a/contrib/restricted/boost/filesystem/src/posix_tools.hpp
+++ b/contrib/restricted/boost/filesystem/src/posix_tools.hpp
@@ -19,10 +19,25 @@
#include <unistd.h>
#endif
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
+
namespace boost {
namespace filesystem {
namespace detail {
+//! Platform-specific parameters for directory iterator construction
+struct directory_iterator_params
+{
+#if defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
+ //! File descriptor of the base directory relative to which to interpret relative paths
+ int basedir_fd;
+#endif
+#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
+ //! File descriptor of the directory over which the iterator iterates
+ int iterator_fd;
+#endif
+};
+
/*!
* Closes a file descriptor and returns the result, similar to close(2). Unlike close(2), guarantees that the file descriptor is closed even if EINTR error happens.
*
@@ -61,4 +76,6 @@ inline int close_fd(int fd)
} // namespace filesystem
} // namespace boost
+#include <boost/filesystem/detail/footer.hpp>
+
#endif // BOOST_FILESYSTEM_SRC_POSIX_TOOLS_HPP_
diff --git a/contrib/restricted/boost/filesystem/src/unique_path.cpp b/contrib/restricted/boost/filesystem/src/unique_path.cpp
index 4815ca43698..f0bc6058cb2 100644
--- a/contrib/restricted/boost/filesystem/src/unique_path.cpp
+++ b/contrib/restricted/boost/filesystem/src/unique_path.cpp
@@ -95,6 +95,8 @@
#include "atomic_tools.hpp"
#include "error_handling.hpp"
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
+
#if defined(BOOST_POSIX_API)
// At least Mac OS X 10.6 and older doesn't support O_CLOEXEC
#ifndef O_CLOEXEC
@@ -325,3 +327,5 @@ path unique_path(path const& model, system::error_code* ec)
} // namespace detail
} // namespace filesystem
} // namespace boost
+
+#include <boost/filesystem/detail/footer.hpp>
diff --git a/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp b/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp
index f7f9f7ef583..7e5939bb718 100644
--- a/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp
+++ b/contrib/restricted/boost/filesystem/src/utf8_codecvt_facet.cpp
@@ -7,6 +7,8 @@
#include <boost/filesystem/config.hpp>
+#include <boost/filesystem/detail/header.hpp>
+
#define BOOST_UTF8_BEGIN_NAMESPACE \
namespace boost { \
namespace filesystem { \
@@ -23,3 +25,5 @@
#undef BOOST_UTF8_BEGIN_NAMESPACE
#undef BOOST_UTF8_END_NAMESPACE
#undef BOOST_UTF8_DECL
+
+#include <boost/filesystem/detail/footer.hpp>
diff --git a/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp b/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp
index 56d1d1d7b3b..f86ba5111b9 100644
--- a/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp
+++ b/contrib/restricted/boost/filesystem/src/windows_file_codecvt.cpp
@@ -19,6 +19,8 @@
#include <windows.h>
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
+
namespace boost {
namespace filesystem {
namespace detail {
@@ -65,4 +67,6 @@ std::codecvt_base::result windows_file_codecvt::do_out(
} // namespace filesystem
} // namespace boost
+#include <boost/filesystem/detail/footer.hpp>
+
#endif // BOOST_WINDOWS_API
diff --git a/contrib/restricted/boost/filesystem/src/windows_file_codecvt.hpp b/contrib/restricted/boost/filesystem/src/windows_file_codecvt.hpp
index fbcf670b114..917dc2182fe 100644
--- a/contrib/restricted/boost/filesystem/src/windows_file_codecvt.hpp
+++ b/contrib/restricted/boost/filesystem/src/windows_file_codecvt.hpp
@@ -19,6 +19,8 @@
#include <cwchar> // std::mbstate_t
#include <locale>
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
+
namespace boost {
namespace filesystem {
namespace detail {
@@ -63,6 +65,8 @@ protected:
} // namespace filesystem
} // namespace boost
+#include <boost/filesystem/detail/footer.hpp>
+
#endif // BOOST_WINDOWS_API
#endif // BOOST_FILESYSTEM_WINDOWS_FILE_CODECVT_HPP
diff --git a/contrib/restricted/boost/filesystem/src/windows_tools.hpp b/contrib/restricted/boost/filesystem/src/windows_tools.hpp
index 469be041ec2..8a2de7f0c9f 100644
--- a/contrib/restricted/boost/filesystem/src/windows_tools.hpp
+++ b/contrib/restricted/boost/filesystem/src/windows_tools.hpp
@@ -21,6 +21,8 @@
#include <windows.h>
+#include <boost/filesystem/detail/header.hpp> // must be the last #include
+
#ifndef IO_REPARSE_TAG_MOUNT_POINT
#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
#endif
@@ -83,6 +85,18 @@ inline bool is_reparse_point_tag_a_symlink(ULONG reparse_point_tag)
#if !defined(UNDER_CE)
+//! Platform-specific parameters for directory iterator construction
+struct directory_iterator_params
+{
+ //! Handle of the directory to iterate over. If not \c INVALID_HANDLE_VALUE, the directory path is ignored.
+ HANDLE use_handle;
+ /*!
+ * If \c use_handle is not \c INVALID_HANDLE_VALUE, specifies whether the directory iterator should close the handle upon destruction.
+ * If \c false, the handle must remain valid for the lifetime of the iterator.
+ */
+ bool close_handle;
+};
+
//! IO_STATUS_BLOCK definition from Windows SDK.
struct io_status_block
{
@@ -102,6 +116,69 @@ struct unicode_string
PWSTR Buffer;
};
+//! OBJECT_ATTRIBUTES definition from Windows SDK
+struct object_attributes
+{
+ ULONG Length;
+ HANDLE RootDirectory;
+ unicode_string* ObjectName;
+ ULONG Attributes;
+ PVOID SecurityDescriptor;
+ PVOID SecurityQualityOfService;
+};
+
+#ifndef OBJ_CASE_INSENSITIVE
+#define OBJ_CASE_INSENSITIVE 0x00000040
+#endif
+#ifndef OBJ_DONT_REPARSE
+#define OBJ_DONT_REPARSE 0x00001000
+#endif
+
+#ifndef FILE_SUPERSEDE
+#define FILE_SUPERSEDE 0x00000000
+#endif
+#ifndef FILE_OPEN
+#define FILE_OPEN 0x00000001
+#endif
+#ifndef FILE_CREATE
+#define FILE_CREATE 0x00000002
+#endif
+#ifndef FILE_OPEN_IF
+#define FILE_OPEN_IF 0x00000003
+#endif
+#ifndef FILE_OVERWRITE
+#define FILE_OVERWRITE 0x00000004
+#endif
+#ifndef FILE_OVERWRITE_IF
+#define FILE_OVERWRITE_IF 0x00000005
+#endif
+
+#ifndef FILE_DIRECTORY_FILE
+#define FILE_DIRECTORY_FILE 0x00000001
+#endif
+#ifndef FILE_OPEN_FOR_BACKUP_INTENT
+#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
+#endif
+#ifndef FILE_OPEN_REPARSE_POINT
+#define FILE_OPEN_REPARSE_POINT 0x00200000
+#endif
+
+//! NtCreateFile signature. Available since Windows 2000 (probably).
+typedef boost::winapi::NTSTATUS_ (NTAPI NtCreateFile_t)(
+ /*out*/ PHANDLE FileHandle,
+ /*in*/ ACCESS_MASK DesiredAccess,
+ /*in*/ object_attributes* ObjectAttributes,
+ /*out*/ io_status_block* IoStatusBlock,
+ /*in, optional*/ PLARGE_INTEGER AllocationSize,
+ /*in*/ ULONG FileAttributes,
+ /*in*/ ULONG ShareAccess,
+ /*in*/ ULONG CreateDisposition,
+ /*in*/ ULONG CreateOptions,
+ /*in, optional*/ PVOID EaBuffer,
+ /*in*/ ULONG EaLength);
+
+extern NtCreateFile_t* nt_create_file_api;
+
//! PIO_APC_ROUTINE definition from Windows SDK
typedef VOID (NTAPI* pio_apc_routine) (PVOID ApcContext, io_status_block* IoStatusBlock, ULONG Reserved);
@@ -113,17 +190,17 @@ enum file_information_class
//! NtQueryDirectoryFile signature. Available since Windows NT 4.0 (probably).
typedef boost::winapi::NTSTATUS_ (NTAPI NtQueryDirectoryFile_t)(
- /*in*/ HANDLE FileHandle,
- /*in, optional*/ HANDLE Event,
- /*in, optional*/ pio_apc_routine ApcRoutine,
- /*in, optional*/ PVOID ApcContext,
- /*out*/ io_status_block* IoStatusBlock,
- /*out*/ PVOID FileInformation,
- /*in*/ ULONG Length,
- /*in*/ file_information_class FileInformationClass,
- /*in*/ BOOLEAN ReturnSingleEntry,
- /*in, optional*/ unicode_string* FileName,
- /*in*/ BOOLEAN RestartScan);
+ /*in*/ HANDLE FileHandle,
+ /*in, optional*/ HANDLE Event,
+ /*in, optional*/ pio_apc_routine ApcRoutine,
+ /*in, optional*/ PVOID ApcContext,
+ /*out*/ io_status_block* IoStatusBlock,
+ /*out*/ PVOID FileInformation,
+ /*in*/ ULONG Length,
+ /*in*/ file_information_class FileInformationClass,
+ /*in*/ BOOLEAN ReturnSingleEntry,
+ /*in, optional*/ unicode_string* FileName,
+ /*in*/ BOOLEAN RestartScan);
extern NtQueryDirectoryFile_t* nt_query_directory_file_api;
@@ -182,8 +259,15 @@ inline HANDLE create_file_handle(boost::filesystem::path const& p, DWORD dwDesir
return ::CreateFileW(p.c_str(), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
+#if !defined(UNDER_CE)
+//! Creates a file handle for a file relative to a previously opened base directory. The file path must be relative and in preferred format.
+boost::winapi::NTSTATUS_ nt_create_file_handle_at(HANDLE& out, HANDLE basedir_handle, boost::filesystem::path const& p, ULONG FileAttributes, ACCESS_MASK DesiredAccess, ULONG ShareMode, ULONG CreateDisposition, ULONG CreateOptions);
+#endif // !defined(UNDER_CE)
+
} // namespace detail
} // namespace filesystem
} // namespace boost
+#include <boost/filesystem/detail/footer.hpp>
+
#endif // BOOST_FILESYSTEM_SRC_WINDOWS_TOOLS_HPP_