mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-03-15 02:35:12 +08:00
Update ghc::filesystem to v1.5.14
This commit is contained in:
parent
7a86ed6508
commit
543603bdfc
@ -67,6 +67,8 @@
|
|||||||
#define GHC_OS_WIN32
|
#define GHC_OS_WIN32
|
||||||
#elif defined(__CYGWIN__)
|
#elif defined(__CYGWIN__)
|
||||||
#define GHC_OS_CYGWIN
|
#define GHC_OS_CYGWIN
|
||||||
|
#elif defined(__sun) && defined(__SVR4)
|
||||||
|
#define GHC_OS_SOLARIS
|
||||||
#elif defined(__svr4__)
|
#elif defined(__svr4__)
|
||||||
#define GHC_OS_SYS5R4
|
#define GHC_OS_SYS5R4
|
||||||
#elif defined(BSD)
|
#elif defined(BSD)
|
||||||
@ -76,7 +78,8 @@
|
|||||||
#include <wasi/api.h>
|
#include <wasi/api.h>
|
||||||
#elif defined(__QNX__)
|
#elif defined(__QNX__)
|
||||||
#define GHC_OS_QNX
|
#define GHC_OS_QNX
|
||||||
#define GHC_NO_DIRENT_D_TYPE
|
#elif defined(__HAIKU__)
|
||||||
|
#define GHC_OS_HAIKU
|
||||||
#else
|
#else
|
||||||
#error "Operating system currently not supported!"
|
#error "Operating system currently not supported!"
|
||||||
#endif
|
#endif
|
||||||
@ -214,6 +217,7 @@
|
|||||||
#include <compare>
|
#include <compare>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#include <chrono>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
@ -253,6 +257,10 @@
|
|||||||
#include <experimental/string_view>
|
#include <experimental/string_view>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(GHC_OS_WINDOWS) && !defined(PATH_MAX)
|
||||||
|
#define PATH_MAX 4096
|
||||||
|
#endif
|
||||||
|
|
||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// Behaviour Switches (see README.md, should match the config in test/filesystem_test.cpp):
|
// Behaviour Switches (see README.md, should match the config in test/filesystem_test.cpp):
|
||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
@ -264,7 +272,7 @@
|
|||||||
// configure LWG conformance ()
|
// configure LWG conformance ()
|
||||||
#define LWG_2682_BEHAVIOUR
|
#define LWG_2682_BEHAVIOUR
|
||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// LWG #2395 makes create_directory/create_directories not emit an error if there is a regular
|
// LWG #2395 makes crate_directory/create_directories not emit an error if there is a regular
|
||||||
// file with that name, it is superseded by P1164R1, so only activate if really needed
|
// file with that name, it is superseded by P1164R1, so only activate if really needed
|
||||||
// #define LWG_2935_BEHAVIOUR
|
// #define LWG_2935_BEHAVIOUR
|
||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
@ -273,19 +281,19 @@
|
|||||||
// * if this->has_root_directory() and !p.has_root_directory() return -1
|
// * if this->has_root_directory() and !p.has_root_directory() return -1
|
||||||
// * if !this->has_root_directory() and p.has_root_directory() return -1
|
// * if !this->has_root_directory() and p.has_root_directory() return -1
|
||||||
// * else result of element wise comparison of path iteration where first comparison is != 0 or 0
|
// * else result of element wise comparison of path iteration where first comparison is != 0 or 0
|
||||||
// if all comparisons are 0 (on Windows this implementation does case insensitive root_name()
|
// if all comparisons are 0 (on Windows this implementation does case-insensitive root_name()
|
||||||
// comparison)
|
// comparison)
|
||||||
#define LWG_2936_BEHAVIOUR
|
#define LWG_2936_BEHAVIOUR
|
||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// LWG #2937 enforces that fs::equivalent emits an error, if !fs::exists(p1)||!exists(p2)
|
// LWG #2937 enforces that fs::equivalent emits an error, if !fs::exists(p1)||!exists(p2)
|
||||||
#define LWG_2937_BEHAVIOUR
|
#define LWG_2937_BEHAVIOUR
|
||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// UTF8-Everywhere is the original behaviour of ghc::filesystem. But since v1.5 the windows
|
// UTF8-Everywhere is the original behaviour of ghc::filesystem. But since v1.5 the Windows
|
||||||
// version defaults to std::wstring storage backend. Still all std::string will be interpreted
|
// version defaults to std::wstring storage backend. Still all std::string will be interpreted
|
||||||
// as UTF-8 encoded. With this define you can enfoce the old behavior on Windows, using
|
// as UTF-8 encoded. With this define you can enforce the old behavior on Windows, using
|
||||||
// std::string as backend and for fs::path::native() and char for fs::path::c_str(). This
|
// std::string as backend and for fs::path::native() and char for fs::path::c_str(). This
|
||||||
// needs more conversions so it is (an was before v1.5) slower, bot might help keeping source
|
// needs more conversions, so it is (and was before v1.5) slower, bot might help keeping source
|
||||||
// homogeneous in a multi platform project.
|
// homogeneous in a multi-platform project.
|
||||||
// #define GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE
|
// #define GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE
|
||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// Raise errors/exceptions when invalid unicode codepoints or UTF-8 sequences are found,
|
// Raise errors/exceptions when invalid unicode codepoints or UTF-8 sequences are found,
|
||||||
@ -300,7 +308,7 @@
|
|||||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
// ghc::filesystem version in decimal (major * 10000 + minor * 100 + patch)
|
// ghc::filesystem version in decimal (major * 10000 + minor * 100 + patch)
|
||||||
#define GHC_FILESYSTEM_VERSION 10509L
|
#define GHC_FILESYSTEM_VERSION 10514L
|
||||||
|
|
||||||
#if !defined(GHC_WITH_EXCEPTIONS) && (defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND))
|
#if !defined(GHC_WITH_EXCEPTIONS) && (defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND))
|
||||||
#define GHC_WITH_EXCEPTIONS
|
#define GHC_WITH_EXCEPTIONS
|
||||||
@ -423,7 +431,8 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
using path_type_EcharT = typename std::enable_if<std::is_same<T, char>::value || std::is_same<T, char8_t>::value || std::is_same<T, char16_t>::value || std::is_same<T, char32_t>::value || std::is_same<T, wchar_t>::value, path>::type;
|
using path_type_EcharT = typename std::enable_if<std::is_same<T, char>::value || std::is_same<T, char8_t>::value || std::is_same<T, char16_t>::value || std::is_same<T, char32_t>::value || std::is_same<T, wchar_t>::value, path>::type;
|
||||||
#else
|
#else
|
||||||
using path_from_string = typename std::enable_if<_is_basic_string<T>::value || std::is_same<char const*, typename std::decay<T>::type>::value || std::is_same<char*, typename std::decay<T>::type>::value ||
|
using path_from_string =
|
||||||
|
typename std::enable_if<_is_basic_string<T>::value || std::is_same<char const*, typename std::decay<T>::type>::value || std::is_same<char*, typename std::decay<T>::type>::value ||
|
||||||
std::is_same<char16_t const*, typename std::decay<T>::type>::value || std::is_same<char16_t*, typename std::decay<T>::type>::value || std::is_same<char32_t const*, typename std::decay<T>::type>::value ||
|
std::is_same<char16_t const*, typename std::decay<T>::type>::value || std::is_same<char16_t*, typename std::decay<T>::type>::value || std::is_same<char32_t const*, typename std::decay<T>::type>::value ||
|
||||||
std::is_same<char32_t*, typename std::decay<T>::type>::value || std::is_same<wchar_t const*, typename std::decay<T>::type>::value || std::is_same<wchar_t*, typename std::decay<T>::type>::value,
|
std::is_same<char32_t*, typename std::decay<T>::type>::value || std::is_same<wchar_t const*, typename std::decay<T>::type>::value || std::is_same<wchar_t*, typename std::decay<T>::type>::value,
|
||||||
path>::type;
|
path>::type;
|
||||||
@ -799,6 +808,7 @@ public:
|
|||||||
file_type type() const noexcept;
|
file_type type() const noexcept;
|
||||||
perms permissions() const noexcept;
|
perms permissions() const noexcept;
|
||||||
friend bool operator==(const file_status& lhs, const file_status& rhs) noexcept { return lhs.type() == rhs.type() && lhs.permissions() == rhs.permissions(); }
|
friend bool operator==(const file_status& lhs, const file_status& rhs) noexcept { return lhs.type() == rhs.type() && lhs.permissions() == rhs.permissions(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
file_type _type;
|
file_type _type;
|
||||||
perms _perms;
|
perms _perms;
|
||||||
@ -1295,6 +1305,65 @@ GHC_FS_API std::error_code make_error_code(portable_error err);
|
|||||||
GHC_FS_API std::error_code make_system_error(uint32_t err = 0);
|
GHC_FS_API std::error_code make_system_error(uint32_t err = 0);
|
||||||
#else
|
#else
|
||||||
GHC_FS_API std::error_code make_system_error(int err = 0);
|
GHC_FS_API std::error_code make_system_error(int err = 0);
|
||||||
|
|
||||||
|
template <typename T, typename = int>
|
||||||
|
struct has_d_type : std::false_type{};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_d_type<T, decltype((void)T::d_type, 0)> : std::true_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
GHC_INLINE file_type file_type_from_dirent_impl(const T&, std::false_type)
|
||||||
|
{
|
||||||
|
return file_type::none;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
GHC_INLINE file_type file_type_from_dirent_impl(const T& t, std::true_type)
|
||||||
|
{
|
||||||
|
switch (t.d_type) {
|
||||||
|
#ifdef DT_BLK
|
||||||
|
case DT_BLK:
|
||||||
|
return file_type::block;
|
||||||
|
#endif
|
||||||
|
#ifdef DT_CHR
|
||||||
|
case DT_CHR:
|
||||||
|
return file_type::character;
|
||||||
|
#endif
|
||||||
|
#ifdef DT_DIR
|
||||||
|
case DT_DIR:
|
||||||
|
return file_type::directory;
|
||||||
|
#endif
|
||||||
|
#ifdef DT_FIFO
|
||||||
|
case DT_FIFO:
|
||||||
|
return file_type::fifo;
|
||||||
|
#endif
|
||||||
|
#ifdef DT_LNK
|
||||||
|
case DT_LNK:
|
||||||
|
return file_type::symlink;
|
||||||
|
#endif
|
||||||
|
#ifdef DT_REG
|
||||||
|
case DT_REG:
|
||||||
|
return file_type::regular;
|
||||||
|
#endif
|
||||||
|
#ifdef DT_SOCK
|
||||||
|
case DT_SOCK:
|
||||||
|
return file_type::socket;
|
||||||
|
#endif
|
||||||
|
#ifdef DT_UNKNOWN
|
||||||
|
case DT_UNKNOWN:
|
||||||
|
return file_type::none;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return file_type::unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
GHC_INLINE file_type file_type_from_dirent(const T& t)
|
||||||
|
{
|
||||||
|
return file_type_from_dirent_impl(t, has_d_type<T>{});
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
@ -1888,10 +1957,15 @@ GHC_INLINE void create_symlink(const path& target_name, const path& new_symlink,
|
|||||||
#if defined(__GNUC__) && __GNUC__ >= 8
|
#if defined(__GNUC__) && __GNUC__ >= 8
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||||
|
#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4191)
|
||||||
#endif
|
#endif
|
||||||
static CreateSymbolicLinkW_fp api_call = reinterpret_cast<CreateSymbolicLinkW_fp>(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateSymbolicLinkW"));
|
static CreateSymbolicLinkW_fp api_call = reinterpret_cast<CreateSymbolicLinkW_fp>(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateSymbolicLinkW"));
|
||||||
#if defined(__GNUC__) && __GNUC__ >= 8
|
#if defined(__GNUC__) && __GNUC__ >= 8
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__)
|
||||||
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
if (api_call) {
|
if (api_call) {
|
||||||
if (api_call(GHC_NATIVEWP(new_symlink), GHC_NATIVEWP(target_name), to_directory ? 1 : 0) == 0) {
|
if (api_call(GHC_NATIVEWP(new_symlink), GHC_NATIVEWP(target_name), to_directory ? 1 : 0) == 0) {
|
||||||
@ -1912,10 +1986,15 @@ GHC_INLINE void create_hardlink(const path& target_name, const path& new_hardlin
|
|||||||
#if defined(__GNUC__) && __GNUC__ >= 8
|
#if defined(__GNUC__) && __GNUC__ >= 8
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||||
|
#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4191)
|
||||||
#endif
|
#endif
|
||||||
static CreateHardLinkW_fp api_call = reinterpret_cast<CreateHardLinkW_fp>(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateHardLinkW"));
|
static CreateHardLinkW_fp api_call = reinterpret_cast<CreateHardLinkW_fp>(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateHardLinkW"));
|
||||||
#if defined(__GNUC__) && __GNUC__ >= 8
|
#if defined(__GNUC__) && __GNUC__ >= 8
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__)
|
||||||
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
if (api_call) {
|
if (api_call) {
|
||||||
if (api_call(GHC_NATIVEWP(new_hardlink), GHC_NATIVEWP(target_name), NULL) == 0) {
|
if (api_call(GHC_NATIVEWP(new_hardlink), GHC_NATIVEWP(target_name), NULL) == 0) {
|
||||||
@ -2004,6 +2083,52 @@ GHC_INLINE file_status file_status_from_st_mode(T mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GHC_OS_WINDOWS
|
#ifdef GHC_OS_WINDOWS
|
||||||
|
|
||||||
|
class unique_handle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef HANDLE element_type;
|
||||||
|
|
||||||
|
unique_handle() noexcept
|
||||||
|
: _handle(INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
explicit unique_handle(element_type h) noexcept
|
||||||
|
: _handle(h)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
unique_handle(unique_handle&& u) noexcept
|
||||||
|
: _handle(u.release())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~unique_handle() { reset(); }
|
||||||
|
unique_handle& operator=(unique_handle&& u) noexcept
|
||||||
|
{
|
||||||
|
reset(u.release());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
element_type get() const noexcept { return _handle; }
|
||||||
|
explicit operator bool() const noexcept { return _handle != INVALID_HANDLE_VALUE; }
|
||||||
|
element_type release() noexcept
|
||||||
|
{
|
||||||
|
element_type tmp = _handle;
|
||||||
|
_handle = INVALID_HANDLE_VALUE;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
void reset(element_type h = INVALID_HANDLE_VALUE) noexcept
|
||||||
|
{
|
||||||
|
element_type tmp = _handle;
|
||||||
|
_handle = h;
|
||||||
|
if (tmp != INVALID_HANDLE_VALUE) {
|
||||||
|
CloseHandle(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void swap(unique_handle& u) noexcept { std::swap(_handle, u._handle); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
element_type _handle;
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef REPARSE_DATA_BUFFER_HEADER_SIZE
|
#ifndef REPARSE_DATA_BUFFER_HEADER_SIZE
|
||||||
typedef struct _REPARSE_DATA_BUFFER
|
typedef struct _REPARSE_DATA_BUFFER
|
||||||
{
|
{
|
||||||
@ -2040,15 +2165,21 @@ typedef struct _REPARSE_DATA_BUFFER
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GHC_INLINE std::shared_ptr<REPARSE_DATA_BUFFER> getReparseData(const path& p, std::error_code& ec)
|
template <class T>
|
||||||
|
struct free_deleter
|
||||||
{
|
{
|
||||||
std::shared_ptr<void> file(CreateFileW(GHC_NATIVEWP(p), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0), CloseHandle);
|
void operator()(T* p) const { std::free(p); }
|
||||||
if (file.get() == INVALID_HANDLE_VALUE) {
|
};
|
||||||
|
|
||||||
|
GHC_INLINE std::unique_ptr<REPARSE_DATA_BUFFER, free_deleter<REPARSE_DATA_BUFFER>> getReparseData(const path& p, std::error_code& ec)
|
||||||
|
{
|
||||||
|
unique_handle file(CreateFileW(GHC_NATIVEWP(p), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0));
|
||||||
|
if (!file) {
|
||||||
ec = detail::make_system_error();
|
ec = detail::make_system_error();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<REPARSE_DATA_BUFFER> reparseData((REPARSE_DATA_BUFFER*)std::calloc(1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE), std::free);
|
std::unique_ptr<REPARSE_DATA_BUFFER, free_deleter<REPARSE_DATA_BUFFER>> reparseData(reinterpret_cast<REPARSE_DATA_BUFFER*>(std::calloc(1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE)));
|
||||||
ULONG bufferUsed;
|
ULONG bufferUsed;
|
||||||
if (DeviceIoControl(file.get(), FSCTL_GET_REPARSE_POINT, 0, 0, reparseData.get(), MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bufferUsed, 0)) {
|
if (DeviceIoControl(file.get(), FSCTL_GET_REPARSE_POINT, 0, 0, reparseData.get(), MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bufferUsed, 0)) {
|
||||||
return reparseData;
|
return reparseData;
|
||||||
@ -2122,10 +2253,10 @@ GHC_INLINE time_t timeFromFILETIME(const FILETIME& ft)
|
|||||||
|
|
||||||
GHC_INLINE void timeToFILETIME(time_t t, FILETIME& ft)
|
GHC_INLINE void timeToFILETIME(time_t t, FILETIME& ft)
|
||||||
{
|
{
|
||||||
LONGLONG ll;
|
ULARGE_INTEGER ull;
|
||||||
ll = Int32x32To64(t, 10000000) + 116444736000000000;
|
ull.QuadPart = static_cast<ULONGLONG>((t * 10000000LL) + 116444736000000000LL);
|
||||||
ft.dwLowDateTime = static_cast<DWORD>(ll);
|
ft.dwLowDateTime = ull.LowPart;
|
||||||
ft.dwHighDateTime = static_cast<DWORD>(ll >> 32);
|
ft.dwHighDateTime = ull.HighPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename INFO>
|
template <typename INFO>
|
||||||
@ -2141,42 +2272,44 @@ GHC_INLINE uintmax_t hard_links_from_INFO<BY_HANDLE_FILE_INFORMATION>(const BY_H
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename INFO>
|
template <typename INFO>
|
||||||
GHC_INLINE DWORD reparse_tag_from_INFO(const INFO*)
|
GHC_INLINE bool is_symlink_from_INFO(const path &p, const INFO* info, std::error_code& ec)
|
||||||
{
|
{
|
||||||
return 0;
|
if ((info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
|
||||||
|
auto reparseData = detail::getReparseData(p, ec);
|
||||||
|
if (!ec && reparseData && IsReparseTagMicrosoft(reparseData->ReparseTag) && reparseData->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
GHC_INLINE DWORD reparse_tag_from_INFO(const WIN32_FIND_DATAW* info)
|
GHC_INLINE bool is_symlink_from_INFO(const path &, const WIN32_FIND_DATAW* info, std::error_code&)
|
||||||
{
|
{
|
||||||
return info->dwReserved0;
|
// dwReserved0 is undefined unless dwFileAttributes includes the
|
||||||
|
// FILE_ATTRIBUTE_REPARSE_POINT attribute according to microsoft
|
||||||
|
// documentation. In practice, dwReserved0 is not reset which
|
||||||
|
// causes it to report the incorrect symlink status.
|
||||||
|
// Note that microsoft documentation does not say whether there is
|
||||||
|
// a null value for dwReserved0, so we test for symlink directly
|
||||||
|
// instead of returning the tag which requires returning a null
|
||||||
|
// value for non-reparse-point files.
|
||||||
|
return (info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && info->dwReserved0 == IO_REPARSE_TAG_SYMLINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename INFO>
|
template <typename INFO>
|
||||||
GHC_INLINE file_status status_from_INFO(const path& p, const INFO* info, std::error_code& ec, uintmax_t* sz = nullptr, time_t* lwt = nullptr)
|
GHC_INLINE file_status status_from_INFO(const path& p, const INFO* info, std::error_code& ec, uintmax_t* sz = nullptr, time_t* lwt = nullptr)
|
||||||
{
|
{
|
||||||
file_type ft = file_type::unknown;
|
file_type ft = file_type::unknown;
|
||||||
if (sizeof(INFO) == sizeof(WIN32_FIND_DATAW)) {
|
if (is_symlink_from_INFO(p, info, ec)) {
|
||||||
if (detail::reparse_tag_from_INFO(info) == IO_REPARSE_TAG_SYMLINK) {
|
|
||||||
ft = file_type::symlink;
|
ft = file_type::symlink;
|
||||||
}
|
}
|
||||||
}
|
else if ((info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||||
else {
|
|
||||||
if ((info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
|
|
||||||
auto reparseData = detail::getReparseData(p, ec);
|
|
||||||
if (!ec && reparseData && IsReparseTagMicrosoft(reparseData->ReparseTag) && reparseData->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
|
|
||||||
ft = file_type::symlink;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ft == file_type::unknown) {
|
|
||||||
if ((info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
|
||||||
ft = file_type::directory;
|
ft = file_type::directory;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ft = file_type::regular;
|
ft = file_type::regular;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
perms prms = perms::owner_read | perms::group_read | perms::others_read;
|
perms prms = perms::owner_read | perms::group_read | perms::others_read;
|
||||||
if (!(info->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
|
if (!(info->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
|
||||||
prms = prms | perms::owner_write | perms::group_write | perms::others_write;
|
prms = prms | perms::owner_write | perms::group_write | perms::others_write;
|
||||||
@ -3056,7 +3189,8 @@ GHC_INLINE bool has_executable_extension(const path& p)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const path::value_type* ext = fn._path.c_str() + pos + 1;
|
const path::value_type* ext = fn._path.c_str() + pos + 1;
|
||||||
if (detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("exe")) || detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("cmd")) || detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("bat")) || detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("com"))) {
|
if (detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("exe")) || detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("cmd")) || detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("bat")) ||
|
||||||
|
detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("com"))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3232,7 +3366,7 @@ GHC_INLINE path::impl_string_type::const_iterator path::iterator::increment(cons
|
|||||||
// we can only sit on a slash if it is a network name or a root
|
// we can only sit on a slash if it is a network name or a root
|
||||||
if (i != _last && *i == preferred_separator) {
|
if (i != _last && *i == preferred_separator) {
|
||||||
if (fromStart && !(i + 1 != _last && *(i + 1) == preferred_separator)) {
|
if (fromStart && !(i + 1 != _last && *(i + 1) == preferred_separator)) {
|
||||||
// leading double slashes detected, treat this and the
|
// leadind double slashes detected, treat this and the
|
||||||
// following until a slash as one unit
|
// following until a slash as one unit
|
||||||
i = std::find(++i, _last, preferred_separator);
|
i = std::find(++i, _last, preferred_separator);
|
||||||
}
|
}
|
||||||
@ -3245,10 +3379,14 @@ GHC_INLINE path::impl_string_type::const_iterator path::iterator::increment(cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#ifdef GHC_OS_WINDOWS
|
||||||
if (fromStart && i != _last && *i == ':') {
|
if (fromStart && i != _last && *i == ':') {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
#endif
|
||||||
i = std::find(i, _last, preferred_separator);
|
i = std::find(i, _last, preferred_separator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3792,11 +3930,14 @@ GHC_INLINE bool copy_file(const path& from, const path& to, copy_options options
|
|||||||
ec = tecf;
|
ec = tecf;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (exists(st) && (!is_regular_file(st) || equivalent(from, to, ec) || (options & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing)) == copy_options::none)) {
|
if (exists(st)) {
|
||||||
|
if ((options & copy_options::skip_existing) == copy_options::skip_existing) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!is_regular_file(st) || equivalent(from, to, ec) || (options & (copy_options::overwrite_existing | copy_options::update_existing)) == copy_options::none) {
|
||||||
ec = tect ? tect : detail::make_error_code(detail::portable_error::exists);
|
ec = tect ? tect : detail::make_error_code(detail::portable_error::exists);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (exists(st)) {
|
|
||||||
if ((options & copy_options::update_existing) == copy_options::update_existing) {
|
if ((options & copy_options::update_existing) == copy_options::update_existing) {
|
||||||
auto from_time = last_write_time(from, ec);
|
auto from_time = last_write_time(from, ec);
|
||||||
if (ec) {
|
if (ec) {
|
||||||
@ -3836,15 +3977,33 @@ GHC_INLINE bool copy_file(const path& from, const path& to, copy_options options
|
|||||||
::close(in);
|
::close(in);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (st.permissions() != sf.permissions()) {
|
||||||
|
if (::fchmod(out, static_cast<mode_t>(sf.permissions() & perms::all)) != 0) {
|
||||||
|
ec = detail::make_system_error();
|
||||||
|
::close(in);
|
||||||
|
::close(out);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
ssize_t br, bw;
|
ssize_t br, bw;
|
||||||
while ((br = ::read(in, buffer.data(), buffer.size())) > 0) {
|
while (true) {
|
||||||
|
do { br = ::read(in, buffer.data(), buffer.size()); } while(errno == EINTR);
|
||||||
|
if(!br) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(br < 0) {
|
||||||
|
ec = detail::make_system_error();
|
||||||
|
::close(in);
|
||||||
|
::close(out);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
ssize_t offset = 0;
|
ssize_t offset = 0;
|
||||||
do {
|
do {
|
||||||
if ((bw = ::write(out, buffer.data() + offset, static_cast<size_t>(br))) > 0) {
|
if ((bw = ::write(out, buffer.data() + offset, static_cast<size_t>(br))) > 0) {
|
||||||
br -= bw;
|
br -= bw;
|
||||||
offset += bw;
|
offset += bw;
|
||||||
}
|
}
|
||||||
else if (bw < 0) {
|
else if (bw < 0 && errno != EINTR) {
|
||||||
ec = detail::make_system_error();
|
ec = detail::make_system_error();
|
||||||
::close(in);
|
::close(in);
|
||||||
::close(out);
|
::close(out);
|
||||||
@ -4079,6 +4238,13 @@ GHC_INLINE path current_path(std::error_code& ec)
|
|||||||
return path();
|
return path();
|
||||||
}
|
}
|
||||||
return path(std::wstring(buffer.get()), path::native_format);
|
return path(std::wstring(buffer.get()), path::native_format);
|
||||||
|
#elif defined(__GLIBC__)
|
||||||
|
std::unique_ptr<char, decltype(&std::free)> buffer { ::getcwd(NULL, 0), std::free };
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
ec = detail::make_system_error();
|
||||||
|
return path();
|
||||||
|
}
|
||||||
|
return path(buffer.get());
|
||||||
#else
|
#else
|
||||||
size_t pathlen = static_cast<size_t>(std::max(int(::pathconf(".", _PC_PATH_MAX)), int(PATH_MAX)));
|
size_t pathlen = static_cast<size_t>(std::max(int(::pathconf(".", _PC_PATH_MAX)), int(PATH_MAX)));
|
||||||
std::unique_ptr<char[]> buffer(new char[pathlen + 1]);
|
std::unique_ptr<char[]> buffer(new char[pathlen + 1]);
|
||||||
@ -4152,10 +4318,10 @@ GHC_INLINE bool equivalent(const path& p1, const path& p2, std::error_code& ec)
|
|||||||
{
|
{
|
||||||
ec.clear();
|
ec.clear();
|
||||||
#ifdef GHC_OS_WINDOWS
|
#ifdef GHC_OS_WINDOWS
|
||||||
std::shared_ptr<void> file1(::CreateFileW(GHC_NATIVEWP(p1), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0), CloseHandle);
|
detail::unique_handle file1(::CreateFileW(GHC_NATIVEWP(p1), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
|
||||||
auto e1 = ::GetLastError();
|
auto e1 = ::GetLastError();
|
||||||
std::shared_ptr<void> file2(::CreateFileW(GHC_NATIVEWP(p2), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0), CloseHandle);
|
detail::unique_handle file2(::CreateFileW(GHC_NATIVEWP(p2), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
|
||||||
if (file1.get() == INVALID_HANDLE_VALUE || file2.get() == INVALID_HANDLE_VALUE) {
|
if (!file1 || !file2) {
|
||||||
#ifdef LWG_2937_BEHAVIOUR
|
#ifdef LWG_2937_BEHAVIOUR
|
||||||
ec = detail::make_system_error(e1 ? e1 : ::GetLastError());
|
ec = detail::make_system_error(e1 ? e1 : ::GetLastError());
|
||||||
#else
|
#else
|
||||||
@ -4245,9 +4411,9 @@ GHC_INLINE uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcep
|
|||||||
ec.clear();
|
ec.clear();
|
||||||
#ifdef GHC_OS_WINDOWS
|
#ifdef GHC_OS_WINDOWS
|
||||||
uintmax_t result = static_cast<uintmax_t>(-1);
|
uintmax_t result = static_cast<uintmax_t>(-1);
|
||||||
std::shared_ptr<void> file(::CreateFileW(GHC_NATIVEWP(p), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0), CloseHandle);
|
detail::unique_handle file(::CreateFileW(GHC_NATIVEWP(p), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
|
||||||
BY_HANDLE_FILE_INFORMATION inf;
|
BY_HANDLE_FILE_INFORMATION inf;
|
||||||
if (file.get() == INVALID_HANDLE_VALUE) {
|
if (!file) {
|
||||||
ec = detail::make_system_error();
|
ec = detail::make_system_error();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -4476,7 +4642,7 @@ GHC_INLINE void last_write_time(const path& p, file_time_type new_time, std::err
|
|||||||
ec.clear();
|
ec.clear();
|
||||||
auto d = new_time.time_since_epoch();
|
auto d = new_time.time_since_epoch();
|
||||||
#ifdef GHC_OS_WINDOWS
|
#ifdef GHC_OS_WINDOWS
|
||||||
std::shared_ptr<void> file(::CreateFileW(GHC_NATIVEWP(p), FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL), ::CloseHandle);
|
detail::unique_handle file(::CreateFileW(GHC_NATIVEWP(p), FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL));
|
||||||
FILETIME ft;
|
FILETIME ft;
|
||||||
auto tt = std::chrono::duration_cast<std::chrono::microseconds>(d).count() * 10 + 116444736000000000;
|
auto tt = std::chrono::duration_cast<std::chrono::microseconds>(d).count() * 10 + 116444736000000000;
|
||||||
ft.dwLowDateTime = static_cast<DWORD>(tt);
|
ft.dwLowDateTime = static_cast<DWORD>(tt);
|
||||||
@ -4484,9 +4650,9 @@ GHC_INLINE void last_write_time(const path& p, file_time_type new_time, std::err
|
|||||||
if (!::SetFileTime(file.get(), 0, 0, &ft)) {
|
if (!::SetFileTime(file.get(), 0, 0, &ft)) {
|
||||||
ec = detail::make_system_error();
|
ec = detail::make_system_error();
|
||||||
}
|
}
|
||||||
#elif defined(GHC_OS_MACOS)
|
#elif defined(GHC_OS_MACOS) && \
|
||||||
#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
|
(__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_13) || (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_11_0) || \
|
||||||
#if __MAC_OS_X_VERSION_MIN_REQUIRED < 101300
|
(__TV_OS_VERSION_MIN_REQUIRED < __TVOS_11_0) || (__WATCH_OS_VERSION_MIN_REQUIRED < __WATCHOS_4_0)
|
||||||
struct ::stat fs;
|
struct ::stat fs;
|
||||||
if (::stat(p.c_str(), &fs) == 0) {
|
if (::stat(p.c_str(), &fs) == 0) {
|
||||||
struct ::timeval tv[2];
|
struct ::timeval tv[2];
|
||||||
@ -4500,18 +4666,6 @@ GHC_INLINE void last_write_time(const path& p, file_time_type new_time, std::err
|
|||||||
}
|
}
|
||||||
ec = detail::make_system_error();
|
ec = detail::make_system_error();
|
||||||
return;
|
return;
|
||||||
#else
|
|
||||||
struct ::timespec times[2];
|
|
||||||
times[0].tv_sec = 0;
|
|
||||||
times[0].tv_nsec = UTIME_OMIT;
|
|
||||||
times[1].tv_sec = std::chrono::duration_cast<std::chrono::seconds>(d).count();
|
|
||||||
times[1].tv_nsec = 0; // std::chrono::duration_cast<std::chrono::nanoseconds>(d).count() % 1000000000;
|
|
||||||
if (::utimensat(AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) {
|
|
||||||
ec = detail::make_system_error();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
#ifndef UTIME_OMIT
|
#ifndef UTIME_OMIT
|
||||||
#define UTIME_OMIT ((1l << 30) - 2l)
|
#define UTIME_OMIT ((1l << 30) - 2l)
|
||||||
@ -4524,7 +4678,7 @@ GHC_INLINE void last_write_time(const path& p, file_time_type new_time, std::err
|
|||||||
#if defined(__ANDROID_API__) && __ANDROID_API__ < 12
|
#if defined(__ANDROID_API__) && __ANDROID_API__ < 12
|
||||||
if (syscall(__NR_utimensat, AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) {
|
if (syscall(__NR_utimensat, AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) {
|
||||||
#else
|
#else
|
||||||
if (::utimensat(AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) {
|
if (::utimensat((int)AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) {
|
||||||
#endif
|
#endif
|
||||||
ec = detail::make_system_error();
|
ec = detail::make_system_error();
|
||||||
}
|
}
|
||||||
@ -4739,7 +4893,7 @@ GHC_INLINE uintmax_t remove_all(const path& p, std::error_code& ec) noexcept
|
|||||||
return static_cast<uintmax_t>(-1);
|
return static_cast<uintmax_t>(-1);
|
||||||
}
|
}
|
||||||
std::error_code tec;
|
std::error_code tec;
|
||||||
auto fs = status(p, tec);
|
auto fs = symlink_status(p, tec);
|
||||||
if (exists(fs) && is_directory(fs)) {
|
if (exists(fs) && is_directory(fs)) {
|
||||||
for (auto iter = directory_iterator(p, ec); iter != directory_iterator(); iter.increment(ec)) {
|
for (auto iter = directory_iterator(p, ec); iter != directory_iterator(); iter.increment(ec)) {
|
||||||
if (ec && !detail::is_not_found_error(ec)) {
|
if (ec && !detail::is_not_found_error(ec)) {
|
||||||
@ -4830,8 +4984,8 @@ GHC_INLINE void resize_file(const path& p, uintmax_t size, std::error_code& ec)
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::shared_ptr<void> file(CreateFileW(GHC_NATIVEWP(p), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL), CloseHandle);
|
detail::unique_handle file(CreateFileW(GHC_NATIVEWP(p), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL));
|
||||||
if (file.get() == INVALID_HANDLE_VALUE) {
|
if (!file) {
|
||||||
ec = detail::make_system_error();
|
ec = detail::make_system_error();
|
||||||
}
|
}
|
||||||
else if (SetFilePointerEx(file.get(), lisize, NULL, FILE_BEGIN) == 0 || SetEndOfFile(file.get()) == 0) {
|
else if (SetFilePointerEx(file.get(), lisize, NULL, FILE_BEGIN) == 0 || SetEndOfFile(file.get()) == 0) {
|
||||||
@ -5139,7 +5293,7 @@ GHC_INLINE void directory_entry::refresh()
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
refresh(ec);
|
refresh(ec);
|
||||||
if (ec) {
|
if (ec && (_status.type() == file_type::none || _symlink_status.type() != file_type::symlink)) {
|
||||||
throw filesystem_error(detail::systemErrorText(ec.value()), _path, ec);
|
throw filesystem_error(detail::systemErrorText(ec.value()), _path, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5550,7 +5704,7 @@ public:
|
|||||||
, _entry(nullptr)
|
, _entry(nullptr)
|
||||||
{
|
{
|
||||||
if (!path.empty()) {
|
if (!path.empty()) {
|
||||||
_dir = ::opendir(path.native().c_str());
|
do { _dir = ::opendir(path.native().c_str()); } while(errno == EINTR);
|
||||||
if (!_dir) {
|
if (!_dir) {
|
||||||
auto error = errno;
|
auto error = errno;
|
||||||
_base = filesystem::path();
|
_base = filesystem::path();
|
||||||
@ -5577,7 +5731,7 @@ public:
|
|||||||
do {
|
do {
|
||||||
skip = false;
|
skip = false;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
_entry = ::readdir(_dir);
|
do { _entry = ::readdir(_dir); } while(errno == EINTR);
|
||||||
if (_entry) {
|
if (_entry) {
|
||||||
_dir_entry._path = _base;
|
_dir_entry._path = _base;
|
||||||
_dir_entry._path.append_name(_entry->d_name);
|
_dir_entry._path.append_name(_entry->d_name);
|
||||||
@ -5591,7 +5745,7 @@ public:
|
|||||||
::closedir(_dir);
|
::closedir(_dir);
|
||||||
_dir = nullptr;
|
_dir = nullptr;
|
||||||
_dir_entry._path.clear();
|
_dir_entry._path.clear();
|
||||||
if (errno) {
|
if (errno && errno != EINTR) {
|
||||||
ec = detail::make_system_error();
|
ec = detail::make_system_error();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -5602,30 +5756,16 @@ public:
|
|||||||
|
|
||||||
void copyToDirEntry()
|
void copyToDirEntry()
|
||||||
{
|
{
|
||||||
#ifdef GHC_NO_DIRENT_D_TYPE
|
|
||||||
_dir_entry._symlink_status = file_status();
|
|
||||||
_dir_entry._status = file_status();
|
|
||||||
#else
|
|
||||||
_dir_entry._symlink_status.permissions(perms::unknown);
|
_dir_entry._symlink_status.permissions(perms::unknown);
|
||||||
switch(_entry->d_type) {
|
auto ft = detail::file_type_from_dirent(*_entry);
|
||||||
case DT_BLK: _dir_entry._symlink_status.type(file_type::block); break;
|
_dir_entry._symlink_status.type(ft);
|
||||||
case DT_CHR: _dir_entry._symlink_status.type(file_type::character); break;
|
if (ft != file_type::symlink) {
|
||||||
case DT_DIR: _dir_entry._symlink_status.type(file_type::directory); break;
|
|
||||||
case DT_FIFO: _dir_entry._symlink_status.type(file_type::fifo); break;
|
|
||||||
case DT_LNK: _dir_entry._symlink_status.type(file_type::symlink); break;
|
|
||||||
case DT_REG: _dir_entry._symlink_status.type(file_type::regular); break;
|
|
||||||
case DT_SOCK: _dir_entry._symlink_status.type(file_type::socket); break;
|
|
||||||
case DT_UNKNOWN: _dir_entry._symlink_status.type(file_type::none); break;
|
|
||||||
default: _dir_entry._symlink_status.type(file_type::unknown); break;
|
|
||||||
}
|
|
||||||
if (_entry->d_type != DT_LNK) {
|
|
||||||
_dir_entry._status = _dir_entry._symlink_status;
|
_dir_entry._status = _dir_entry._symlink_status;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_dir_entry._status.type(file_type::none);
|
_dir_entry._status.type(file_type::none);
|
||||||
_dir_entry._status.permissions(perms::unknown);
|
_dir_entry._status.permissions(perms::unknown);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
_dir_entry._file_size = static_cast<uintmax_t>(-1);
|
_dir_entry._file_size = static_cast<uintmax_t>(-1);
|
||||||
_dir_entry._hard_link_count = static_cast<uintmax_t>(-1);
|
_dir_entry._hard_link_count = static_cast<uintmax_t>(-1);
|
||||||
_dir_entry._last_write_time = 0;
|
_dir_entry._last_write_time = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user