From f6d7d5b826df84bc76947318525f3d814fb61cd2 Mon Sep 17 00:00:00 2001 From: actboy168 Date: Fri, 8 Apr 2022 10:32:41 +0800 Subject: [PATCH 01/25] Fixes skip_existing --- include/ghc/filesystem.hpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 9540b44..6150b3d 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -3912,11 +3912,14 @@ GHC_INLINE bool copy_file(const path& from, const path& to, copy_options options ec = tecf; 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)) { - ec = tect ? tect : detail::make_error_code(detail::portable_error::exists); - return false; - } 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); + return false; + } if ((options & copy_options::update_existing) == copy_options::update_existing) { auto from_time = last_write_time(from, ec); if (ec) { From ab8a78d806f2a703680a57d782a65c3a8f892fb6 Mon Sep 17 00:00:00 2001 From: actboy168 Date: Fri, 8 Apr 2022 11:18:01 +0800 Subject: [PATCH 02/25] copy_file also copies permissions --- include/ghc/filesystem.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 9540b44..2d96915 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -3956,6 +3956,14 @@ GHC_INLINE bool copy_file(const path& from, const path& to, copy_options options ::close(in); return false; } + if (st.permissions() != sf.permissions()) { + if (::fchmod(out, static_cast(sf.permissions() & perms::all)) != 0) { + ec = detail::make_system_error(); + ::close(in); + ::close(out); + return false; + } + } ssize_t br, bw; while ((br = ::read(in, buffer.data(), buffer.size())) > 0) { ssize_t offset = 0; From 28f7c929e07e0f0ada2332810ab38b68cb1e5342 Mon Sep 17 00:00:00 2001 From: actboy168 Date: Fri, 8 Apr 2022 11:43:15 +0800 Subject: [PATCH 03/25] fixes --- include/ghc/filesystem.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 2d96915..8632e91 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -3957,7 +3957,7 @@ GHC_INLINE bool copy_file(const path& from, const path& to, copy_options options return false; } if (st.permissions() != sf.permissions()) { - if (::fchmod(out, static_cast(sf.permissions() & perms::all)) != 0) { + if (::fchmod(out, static_cast(sf.permissions() & perms::all)) != 0) { ec = detail::make_system_error(); ::close(in); ::close(out); From 089ef64aa3d8d9fe326cd4f5d4ef85186afc04a8 Mon Sep 17 00:00:00 2001 From: David Runge Date: Fri, 10 Jun 2022 15:25:02 +0200 Subject: [PATCH 04/25] Declare version in cmake project() call CMakeLists.txt: Declare the project's version in the cmake project() call so that it may be exported to the project's cmake integration (used by other projects). --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7886167..ff712e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,8 @@ cmake_minimum_required(VERSION 3.7.2) -project(ghcfilesystem) +project( + ghcfilesystem, + VERSION 1.5.12 +) if (POLICY CMP0077) cmake_policy(SET CMP0077 NEW) From 4c33b91fe98d5383c391b5ac2a1b2c990519dd6c Mon Sep 17 00:00:00 2001 From: David Runge Date: Fri, 10 Jun 2022 15:44:04 +0200 Subject: [PATCH 05/25] Write ghc_filesystem-config-version.cmake file CMakeLists.txt: Write a ghc_filesystem-config-version.cmake file and install it, so that other projects may rely on the exact version of ghc_filesystem. The compatibility mode implies, that any version of ghc_filesystem with the same major version is feature compatible. --- CMakeLists.txt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff712e1..8995f26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,16 @@ if(GHC_FILESYSTEM_WITH_INSTALL) "${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ghc_filesystem" PATH_VARS CMAKE_INSTALL_INCLUDEDIR) - install(FILES "${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ghc_filesystem") + write_basic_package_version_file( + "${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config-version.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion + ) + install( + FILES + "${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config.cmake" + "${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config-version.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ghc_filesystem" + ) add_library(ghcFilesystem::ghc_filesystem ALIAS ghc_filesystem) endif() From 404c57f1b0dcbd327d0f03cd1e8a1839b065431e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 27 Jul 2022 18:31:16 +0200 Subject: [PATCH 06/25] Fix ghc::filesystem::last_write_time() setter on iOS/tvOS/watchOS The previous implementation tried to detect old deployment targets for macOS that doesn't have the newer `utimensat` call. Unfortunately, it would just detect macOS, and didn't check for the corresponding iOS/tvOS/watchOS version numbers. On those platforms, last_write_time() was effectively a no-op, failing silently and not modifying the mtime of the file. This patch adds detection for these platforms. It also removes the special casing when newer versions of macOS/iOS/tvOS/watchOS are used as the deployment targets, and instead folds it into the default POSIX branch. --- include/ghc/filesystem.hpp | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 9540b44..88c9106 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -4604,9 +4604,9 @@ GHC_INLINE void last_write_time(const path& p, file_time_type new_time, std::err if (!::SetFileTime(file.get(), 0, 0, &ft)) { ec = detail::make_system_error(); } -#elif defined(GHC_OS_MACOS) -#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED -#if __MAC_OS_X_VERSION_MIN_REQUIRED < 101300 +#elif defined(GHC_OS_MACOS) && \ + (__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_13) || (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_11_0) || \ + (__TV_OS_VERSION_MIN_REQUIRED < __TVOS_11_0) || (__WATCH_OS_VERSION_MIN_REQUIRED < __WATCHOS_4_0) struct ::stat fs; if (::stat(p.c_str(), &fs) == 0) { struct ::timeval tv[2]; @@ -4620,18 +4620,6 @@ GHC_INLINE void last_write_time(const path& p, file_time_type new_time, std::err } ec = detail::make_system_error(); 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(d).count(); - times[1].tv_nsec = 0; // std::chrono::duration_cast(d).count() % 1000000000; - if (::utimensat(AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { - ec = detail::make_system_error(); - } - return; -#endif -#endif #else #ifndef UTIME_OMIT #define UTIME_OMIT ((1l << 30) - 2l) From d3d968e5835f449d7ea715f45160db81ea906303 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Tue, 16 Aug 2022 20:29:54 +0200 Subject: [PATCH 07/25] Fix build on GNU/Hurd There is no path length limitation there, even via pathconf. But glibc provides a getcwd function that allocates the buffer dynamically so we can just leverage that. --- include/ghc/filesystem.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 9540b44..8cc504e 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -4199,6 +4199,13 @@ GHC_INLINE path current_path(std::error_code& ec) return path(); } return path(std::wstring(buffer.get()), path::native_format); +#elif defined(__GLIBC__) + std::unique_ptr buffer { ::getcwd(NULL, 0), std::free }; + if (buffer == nullptr) { + ec = detail::make_system_error(); + return path(); + } + return path(buffer.get()); #else size_t pathlen = static_cast(std::max(int(::pathconf(".", _PC_PATH_MAX)), int(PATH_MAX))); std::unique_ptr buffer(new char[pathlen + 1]); From f0caeb7d582b1e5db8999a3d905dffc4706b1811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jianxiang=20Wang=20=28=E7=8E=8B=E5=81=A5=E7=BF=94=29?= Date: Thu, 16 Feb 2023 13:38:48 +0800 Subject: [PATCH 08/25] Update filesystem.hpp Fix directory iterator treating all files subsequent to a symlink as symlink on Windows --- include/ghc/filesystem.hpp | 46 ++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 485bd44..8298b4c 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -2260,41 +2260,43 @@ GHC_INLINE uintmax_t hard_links_from_INFO(const BY_H } template -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 <> -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 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; - if (sizeof(INFO) == sizeof(WIN32_FIND_DATAW)) { - if (detail::reparse_tag_from_INFO(info) == IO_REPARSE_TAG_SYMLINK) { - ft = file_type::symlink; - } + if (is_symlink_from_INFO(p, info, ec)) { + ft = file_type::symlink; + } + else if ((info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + ft = file_type::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; - } - else { - ft = file_type::regular; - } + ft = file_type::regular; } perms prms = perms::owner_read | perms::group_read | perms::others_read; if (!(info->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { From 9afb43851d64a4ed67b96332e8c5a48afdf9d308 Mon Sep 17 00:00:00 2001 From: begasus Date: Sat, 18 Feb 2023 10:21:53 +0100 Subject: [PATCH 09/25] filesystem.hpp, add support for Haiku --- include/ghc/filesystem.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 1d39b81..3ae48f2 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -78,6 +78,8 @@ #include #elif defined(__QNX__) #define GHC_OS_QNX +#elif defined(__HAIKU__) +#define GHC_OS_HAIKU #else #error "Operating system currently not supported!" #endif From a9c18e0880a8289bbbb062d8ba356e9a6ff1cbc5 Mon Sep 17 00:00:00 2001 From: begasus Date: Sun, 19 Feb 2023 09:11:34 +0100 Subject: [PATCH 10/25] Fix Haiku build --- cmake/GhcHelper.cmake | 9 +++++++++ test/CMakeLists.txt | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/cmake/GhcHelper.cmake b/cmake/GhcHelper.cmake index ca0f787..4d9e5a0 100644 --- a/cmake/GhcHelper.cmake +++ b/cmake/GhcHelper.cmake @@ -22,6 +22,9 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND (CMAKE_CXX_COMPILER_VERSION V if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") target_link_libraries(filesystem_test xnet) endif() + if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku") + target_link_libraries(filesystem_test network) + endif() target_compile_definitions(${targetName} PRIVATE USE_STD_FS) endif() @@ -34,6 +37,9 @@ if (CMAKE_COMPILER_IS_GNUCXX AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 8.0 O if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") target_link_libraries(${targetName} xnet) endif() + if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku") + target_link_libraries(${targetName} network) + endif() target_compile_options(${targetName} PRIVATE $<$:-Wa,-mbig-obj>) target_compile_definitions(${targetName} PRIVATE USE_STD_FS) endif() @@ -55,6 +61,9 @@ macro(AddTestExecutableWithStdCpp cppStd) if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") target_link_libraries(filesystem_test_cpp${cppStd} xnet) endif() + if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku") + target_link_libraries(filesystem_test_cpp${cppStd} network) + endif() target_compile_options(filesystem_test_cpp${cppStd} PRIVATE $<$:-s DISABLE_EXCEPTION_CATCHING=0> $<$,$>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror -Wno-error=deprecated-declarations> diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index cf7237e..2275c61 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -25,6 +25,9 @@ if(GHC_COVERAGE) if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") target_link_libraries(filesystem_test PUBLIC xnet) endif() + if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku") + target_link_libraries(filesystem_test PUBLIC network) + endif() if("cxx_std_17" IN_LIST GHC_FILESYSTEM_TEST_COMPILE_FEATURES) AddTestExecutableWithStdCpp(17 filesystem_test.cpp catch.hpp) endif() @@ -38,6 +41,9 @@ else() if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") target_link_libraries(filesystem_test xnet) endif() + if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku") + target_link_libraries(filesystem_test network) + endif() SetTestCompileOptions(filesystem_test) if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) target_compile_definitions(filesystem_test PRIVATE _CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN NOMINMAX) @@ -77,6 +83,9 @@ target_link_libraries(fwd_impl_test ghc_filesystem) if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") target_link_libraries(fwd_impl_test xnet) endif() +if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku") + target_link_libraries(fwd_impl_test network) +endif() SetTestCompileOptions(fwd_impl_test) if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) target_compile_definitions(fwd_impl_test PRIVATE _CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN NOMINMAX) From efc077f5532a2dde03043c330fa63fe974bbc6e6 Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Thu, 2 Mar 2023 08:18:42 +0100 Subject: [PATCH 11/25] refs #156: Windows path handling artifact bled into POSIX --- include/ghc/filesystem.hpp | 4 ++++ test/filesystem_test.cpp | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 9540b44..69edaef 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -3365,10 +3365,14 @@ GHC_INLINE path::impl_string_type::const_iterator path::iterator::increment(cons } } else { +#ifdef GHC_OS_WINDOWS if (fromStart && i != _last && *i == ':') { ++i; } else { +#else + { +#endif i = std::find(i, _last, preferred_separator); } } diff --git a/test/filesystem_test.cpp b/test/filesystem_test.cpp index 23aeb95..cb08839 100644 --- a/test/filesystem_test.cpp +++ b/test/filesystem_test.cpp @@ -790,6 +790,9 @@ TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path. CHECK(fs::path("C:/foo").filename() == "foo"); CHECK(fs::path("C:\\foo").filename() == "foo"); CHECK(fs::path("C:foo").filename() == "foo"); + CHECK(fs::path("t:est.txt").filename() == "est.txt"); +#else + CHECK(fs::path("t:est.txt").filename() == "t:est.txt"); #endif // stem() @@ -807,6 +810,11 @@ TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path. CHECK(fs::path("/foo/.profile").stem() == ".profile"); CHECK(fs::path(".bar").stem() == ".bar"); CHECK(fs::path("..bar").stem() == "."); +#ifdef GHC_OS_WINDOWS + CHECK(fs::path("t:est.txt").stem() == "est"); +#else + CHECK(fs::path("t:est.txt").stem() == "t:est"); +#endif // extension() CHECK(fs::path("/foo/bar.txt").extension() == ".txt"); @@ -814,6 +822,7 @@ TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path. CHECK(fs::path("/foo/.profile").extension() == ""); CHECK(fs::path(".bar").extension() == ""); CHECK(fs::path("..bar").extension() == ".bar"); + CHECK(fs::path("t:est.txt").extension() == ".txt"); if (has_host_root_name_support()) { // //host-based root-names From c8113e14b10281671ff6bf971c6c1d6dfa661257 Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Thu, 2 Mar 2023 19:19:22 +0100 Subject: [PATCH 12/25] Updated readme, bumped to wip version as preparation of upcoming release. --- README.md | 17 +++++++++++++++++ include/ghc/filesystem.hpp | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index db1b2f9..c0e762a 100644 --- a/README.md +++ b/README.md @@ -584,6 +584,23 @@ to the expected behavior. ## Release Notes +### v1.5.13 (wip) + +* Pull request [#163](https://github.com/gulrak/filesystem/pull/163), build + support for Haiku (also fixes [#159](https://github.com/gulrak/filesystem/issues/159)) +* Pull request [#162](https://github.com/gulrak/filesystem/pull/162), fix for + directory iterator treating all files subsequent to a symlink as symlink + on Windows +* Fix for [#156](https://github.com/gulrak/filesystem/issues/156), on POSIX + `stem()`, `filename()` and `extension()` of `fs::path` would return wrong + result if a colon was in the filename +* Pull request [#154](https://github.com/gulrak/filesystem/pull/145), build + support for GNU/Hurd +* Pull request [#153](https://github.com/gulrak/filesystem/pull/153), fixed + `fs::last_write_time(path, time, ec)` setter on iOS, tvOS and watchOS +* Pull request [#145](https://github.com/gulrak/filesystem/pull/145), fix for + Y2038 bug in timeToFILETIME on Windows + ### [v1.5.12](https://github.com/gulrak/filesystem/releases/tag/v1.5.12) * Fix for [#142](https://github.com/gulrak/filesystem/issues/142), removed need diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 3d24219..2db0094 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -308,7 +308,7 @@ //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ghc::filesystem version in decimal (major * 10000 + minor * 100 + patch) -#define GHC_FILESYSTEM_VERSION 10512L +#define GHC_FILESYSTEM_VERSION 10513L #if !defined(GHC_WITH_EXCEPTIONS) && (defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)) #define GHC_WITH_EXCEPTIONS From 4041174f967c86b0a189ef7e203d8a10f0b12b37 Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Thu, 2 Mar 2023 19:46:12 +0100 Subject: [PATCH 13/25] Disabled the defunct drone build. --- .drone.yml => .drone.yml-disabled | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .drone.yml => .drone.yml-disabled (100%) diff --git a/.drone.yml b/.drone.yml-disabled similarity index 100% rename from .drone.yml rename to .drone.yml-disabled From f3033c29fb8e04a4010c2af3c3152f4f10c626a0 Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Fri, 3 Mar 2023 06:44:58 +0100 Subject: [PATCH 14/25] refs #146, added EINTR handling to directory iteration and file copying --- include/ghc/filesystem.hpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 2db0094..5f04a54 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -3965,14 +3965,24 @@ GHC_INLINE bool copy_file(const path& from, const path& to, copy_options options return false; } 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; do { if ((bw = ::write(out, buffer.data() + offset, static_cast(br))) > 0) { br -= bw; offset += bw; } - else if (bw < 0) { + else if (bw < 0 && errno != EINTR) { ec = detail::make_system_error(); ::close(in); ::close(out); @@ -5673,7 +5683,7 @@ public: , _entry(nullptr) { if (!path.empty()) { - _dir = ::opendir(path.native().c_str()); + do { _dir = ::opendir(path.native().c_str()); } while(errno == EINTR); if (!_dir) { auto error = errno; _base = filesystem::path(); @@ -5700,7 +5710,7 @@ public: do { skip = false; errno = 0; - _entry = ::readdir(_dir); + do { _entry = ::readdir(_dir); } while(errno == EINTR); if (_entry) { _dir_entry._path = _base; _dir_entry._path.append_name(_entry->d_name); @@ -5714,7 +5724,7 @@ public: ::closedir(_dir); _dir = nullptr; _dir_entry._path.clear(); - if (errno) { + if (errno && errno != EINTR) { ec = detail::make_system_error(); } break; From f3c1058928991927cf85dc1a286c328f6a98beca Mon Sep 17 00:00:00 2001 From: gulrak Date: Fri, 3 Mar 2023 06:53:13 +0100 Subject: [PATCH 15/25] Update CMakeLists.txt The projects compatibility rule is that minor changes can be api changes, so I changed it to SameMinorVersion. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8995f26..342199b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,7 @@ if(GHC_FILESYSTEM_WITH_INSTALL) write_basic_package_version_file( "${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config-version.cmake" VERSION ${PROJECT_VERSION} - COMPATIBILITY SameMajorVersion + COMPATIBILITY SameMinorVersion ) install( FILES From b1ff2ce95ec606653fb2c1bc45dda11fb62e818c Mon Sep 17 00:00:00 2001 From: gulrak Date: Fri, 3 Mar 2023 17:48:35 +0100 Subject: [PATCH 16/25] Changed version to in-between releases version 1.5.13 As the master version is on that number it avoids confusion. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 342199b..7529614 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.7.2) project( ghcfilesystem, - VERSION 1.5.12 + VERSION 1.5.13 ) if (POLICY CMP0077) From 7da9be91c94a19662ffa1f5b3ebd2b39b46cbdeb Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Fri, 3 Mar 2023 23:42:44 +0100 Subject: [PATCH 17/25] test for permission copying --- test/filesystem_test.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/test/filesystem_test.cpp b/test/filesystem_test.cpp index cb08839..96c379a 100644 --- a/test/filesystem_test.cpp +++ b/test/filesystem_test.cpp @@ -99,7 +99,7 @@ using fstream = ghc::filesystem::fstream; //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template -std::time_t to_time_t(TP tp) +static std::time_t to_time_t(TP tp) { using namespace std::chrono; auto sctp = time_point_cast(tp - TP::clock::now() + system_clock::now()); @@ -107,7 +107,7 @@ std::time_t to_time_t(TP tp) } template -TP from_time_t(std::time_t t) +static TP from_time_t(std::time_t t) { using namespace std::chrono; auto sctp = system_clock::from_time_t(t); @@ -214,7 +214,7 @@ static void generateFile(const fs::path& pathname, int withSize = -1) } #ifdef GHC_OS_WINDOWS -inline bool isWow64Proc() +static bool isWow64Proc() { typedef BOOL(WINAPI * IsWow64Process_t)(HANDLE, PBOOL); BOOL bIsWow64 = FALSE; @@ -303,13 +303,13 @@ public: }; template -bool operator==(TestAllocator const&, TestAllocator const&) noexcept +static bool operator==(TestAllocator const&, TestAllocator const&) noexcept { return true; } template -bool operator!=(TestAllocator const& x, TestAllocator const& y) noexcept +static bool operator!=(TestAllocator const& x, TestAllocator const& y) noexcept { return !(x == y); } @@ -1208,7 +1208,7 @@ TEST_CASE("fs.class.filesystem_error - class filesystem_error", "[filesystem][fi CHECK(fse.path2() == "some/other"); } -constexpr fs::perms constExprOwnerAll() +static constexpr fs::perms constExprOwnerAll() { return fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec; } @@ -1787,6 +1787,19 @@ TEST_CASE("fs.op.copy_file - copy_file", "[filesystem][operations][fs.op.copy_fi CHECK_NOTHROW(fs::copy_file("foobar", "foobar2", ec)); CHECK(ec); CHECK(!fs::exists("foobar")); + fs::path file1("temp1.txt"); + fs::path file2("temp2.txt"); + generateFile(file1, 200); + generateFile(file2, 200); + auto allWrite = fs::perms::owner_write | fs::perms::group_write | fs::perms::others_write; + CHECK_NOTHROW(fs::permissions(file1, allWrite, fs::perm_options::remove)); + CHECK((fs::status(file1).permissions() & fs::perms::owner_write) != fs::perms::owner_write); + CHECK_NOTHROW(fs::permissions(file2, allWrite, fs::perm_options::add)); + CHECK((fs::status(file2).permissions() & fs::perms::owner_write) == fs::perms::owner_write); + fs::copy_file(file1, file2, fs::copy_options::overwrite_existing); + CHECK((fs::status(file2).permissions() & fs::perms::owner_write) != fs::perms::owner_write); + CHECK_NOTHROW(fs::permissions(file1, allWrite, fs::perm_options::add)); + CHECK_NOTHROW(fs::permissions(file2, allWrite, fs::perm_options::add)); } TEST_CASE("fs.op.copy_symlink - copy_symlink", "[filesystem][operations][fs.op.copy_symlink]") From a7a6d930fb1b4ced00e382d4ffc3b3082271dc8a Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Fri, 3 Mar 2023 23:43:08 +0100 Subject: [PATCH 18/25] Updated README.md --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c0e762a..79788f4 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,9 @@ macOS 10.12/10.14/10.15/11.6, Windows 10, Ubuntu 18.04, Ubuntu 20.04, CentOS 7, Alpine ARM/ARM64 Linux and Solaris 10 but should work on other systems too, as long as you have at least a C++11 compatible compiler. It should work with Android NDK, Emscripten and I even had reports of it being used on iOS (within sandboxing constraints) and with v1.5.6 there -is experimental support for QNX. The support of Android NDK, Emscripten and QNX is not -backed up by automated testing but PRs and bug reports are welcome for those too. +is experimental support for QNX. The support of Android NDK, Emscripten, QNX, GNU/Hurd and Haiku is not +backed up by automated testing but PRs and bug reports are welcome for those too and they are reported +to work. It is of course in its own namespace `ghc::filesystem` to not interfere with a regular `std::filesystem` should you use it in a mixed C++17 environment (which is possible). @@ -598,8 +599,14 @@ to the expected behavior. support for GNU/Hurd * Pull request [#153](https://github.com/gulrak/filesystem/pull/153), fixed `fs::last_write_time(path, time, ec)` setter on iOS, tvOS and watchOS +* Pull request [#149](https://github.com/gulrak/filesystem/pull/149), add + version to CMake project and export it * Pull request [#145](https://github.com/gulrak/filesystem/pull/145), fix for Y2038 bug in timeToFILETIME on Windows +* Pull request [#144](https://github.com/gulrak/filesystem/pull/144), `fs::copy_file()` + now also copies the permissions +* Pull request [#143](https://github.com/gulrak/filesystem/pull/143), fix + for `fs::copy_file()` ignoring the `skip_existing` option. ### [v1.5.12](https://github.com/gulrak/filesystem/releases/tag/v1.5.12) From 6a94e84da48b9c013ff848fe783ca1be66e0251f Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Sat, 4 Mar 2023 09:59:16 +0100 Subject: [PATCH 19/25] refs #151, stop throwing on fs::de::refresh for broken symlinks, and added test --- include/ghc/filesystem.hpp | 2 +- test/filesystem_test.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 19e688e..111745a 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -5273,7 +5273,7 @@ GHC_INLINE void directory_entry::refresh() { std::error_code 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); } } diff --git a/test/filesystem_test.cpp b/test/filesystem_test.cpp index 96c379a..6b9801c 100644 --- a/test/filesystem_test.cpp +++ b/test/filesystem_test.cpp @@ -1386,6 +1386,16 @@ TEST_CASE("fs.dir.entry - class directory_entry", "[filesystem][directory_entry] CHECK(!(d2 != d2)); CHECK(d1 == d1); CHECK(!(d1 == d2)); + if(is_symlink_creation_supported()) { + fs::create_symlink(t.path() / "nonexistent", t.path() / "broken"); + for (auto d3 : fs::directory_iterator(t.path())) { + CHECK_NOTHROW(d3.symlink_status()); + CHECK_NOTHROW(d3.status()); + CHECK_NOTHROW(d3.refresh()); + } + fs::directory_entry entry(t.path() / "broken"); + CHECK_NOTHROW(entry.refresh()); + } } TEST_CASE("fs.class.directory_iterator - class directory_iterator", "[filesystem][directory_iterator][fs.class.directory_iterator]") From e3341b2f64126255efef7ecca1974a46b63033a7 Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Sat, 4 Mar 2023 12:03:12 +0100 Subject: [PATCH 20/25] refs #146, fix mingw build issue --- test/filesystem_test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/filesystem_test.cpp b/test/filesystem_test.cpp index 6b9801c..97af80c 100644 --- a/test/filesystem_test.cpp +++ b/test/filesystem_test.cpp @@ -214,6 +214,7 @@ static void generateFile(const fs::path& pathname, int withSize = -1) } #ifdef GHC_OS_WINDOWS +#if !defined(_WIN64) && defined(KEY_WOW64_64KEY) static bool isWow64Proc() { typedef BOOL(WINAPI * IsWow64Process_t)(HANDLE, PBOOL); @@ -226,6 +227,7 @@ static bool isWow64Proc() } return bIsWow64 == TRUE; } +#endif static bool is_symlink_creation_supported() { From 2a81c2c355d16403259671faaa13ad3382386dfb Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Sat, 4 Mar 2023 12:43:22 +0100 Subject: [PATCH 21/25] refs #160, only enable install target by default if not subproject as documented --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7529614..9db3515 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) else() option(GHC_FILESYSTEM_BUILD_EXAMPLES "Build examples" OFF) option(GHC_FILESYSTEM_BUILD_TESTING "Enable tests" OFF) - option(GHC_FILESYSTEM_WITH_INSTALL "With install target" ON) + option(GHC_FILESYSTEM_WITH_INSTALL "With install target" OFF) endif() option(GHC_FILESYSTEM_BUILD_STD_TESTING "Enable STD tests" ${GHC_FILESYSTEM_BUILD_TESTING}) if(NOT DEFINED GHC_FILESYSTEM_TEST_COMPILE_FEATURES) From 9ffca3839f465084a8393601e1bba2b3bac00bcb Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Sat, 4 Mar 2023 12:52:41 +0100 Subject: [PATCH 22/25] Updated README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 79788f4..f6dd4a3 100644 --- a/README.md +++ b/README.md @@ -592,6 +592,9 @@ to the expected behavior. * Pull request [#162](https://github.com/gulrak/filesystem/pull/162), fix for directory iterator treating all files subsequent to a symlink as symlink on Windows +* Fix for [#160](https://github.com/gulrak/filesystem/issues/160), the cmake + config now only sets install targets by default if the project is no + subproject, as documented * Fix for [#156](https://github.com/gulrak/filesystem/issues/156), on POSIX `stem()`, `filename()` and `extension()` of `fs::path` would return wrong result if a colon was in the filename @@ -599,6 +602,10 @@ to the expected behavior. support for GNU/Hurd * Pull request [#153](https://github.com/gulrak/filesystem/pull/153), fixed `fs::last_write_time(path, time, ec)` setter on iOS, tvOS and watchOS +* Fix for [#151](https://github.com/gulrak/filesystem/issues/156), + `fs::directory_entry::refresh()` now, consistently with `status()` will not + throw on symlinks to non-existing targets, but make the entry have + `file_type::not_found` as the type * Pull request [#149](https://github.com/gulrak/filesystem/pull/149), add version to CMake project and export it * Pull request [#145](https://github.com/gulrak/filesystem/pull/145), fix for From 9df22d5396da644ac00043a706b8ef1b75660d72 Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Sat, 4 Mar 2023 15:17:13 +0100 Subject: [PATCH 23/25] refs #157, suppress unavoidable warning at cast for GetProcAddress on MSVC --- include/ghc/filesystem.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 111745a..ac8c738 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -1957,10 +1957,15 @@ GHC_INLINE void create_symlink(const path& target_name, const path& new_symlink, #if defined(__GNUC__) && __GNUC__ >= 8 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-function-type" +#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable : 4191) #endif static CreateSymbolicLinkW_fp api_call = reinterpret_cast(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateSymbolicLinkW")); #if defined(__GNUC__) && __GNUC__ >= 8 #pragma GCC diagnostic pop +#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__) +#pragma warning(pop) #endif if (api_call) { if (api_call(GHC_NATIVEWP(new_symlink), GHC_NATIVEWP(target_name), to_directory ? 1 : 0) == 0) { @@ -1981,10 +1986,15 @@ GHC_INLINE void create_hardlink(const path& target_name, const path& new_hardlin #if defined(__GNUC__) && __GNUC__ >= 8 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-function-type" +#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable : 4191) #endif static CreateHardLinkW_fp api_call = reinterpret_cast(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateHardLinkW")); #if defined(__GNUC__) && __GNUC__ >= 8 #pragma GCC diagnostic pop +#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__) +#pragma warning(pop) #endif if (api_call) { if (api_call(GHC_NATIVEWP(new_hardlink), GHC_NATIVEWP(target_name), NULL) == 0) { From 78b746d901f8ab47e593333fefd82d5254408540 Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Sat, 4 Mar 2023 15:19:18 +0100 Subject: [PATCH 24/25] update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f6dd4a3..6856438 100644 --- a/README.md +++ b/README.md @@ -595,6 +595,8 @@ to the expected behavior. * Fix for [#160](https://github.com/gulrak/filesystem/issues/160), the cmake config now only sets install targets by default if the project is no subproject, as documented +* Fix for [#157](https://github.com/gulrak/filesystem/issues/157), suppress + C4191 warning on MSVC for GetProcAddress casts * Fix for [#156](https://github.com/gulrak/filesystem/issues/156), on POSIX `stem()`, `filename()` and `extension()` of `fs::path` would return wrong result if a colon was in the filename From d1f0d790547a6d2d6e94e7fdabd8516b265148ca Mon Sep 17 00:00:00 2001 From: Steffen Schuemann Date: Sat, 4 Mar 2023 16:42:22 +0100 Subject: [PATCH 25/25] updated README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 6856438..61966f6 100644 --- a/README.md +++ b/README.md @@ -610,6 +610,9 @@ to the expected behavior. `file_type::not_found` as the type * Pull request [#149](https://github.com/gulrak/filesystem/pull/149), add version to CMake project and export it +* Fix for [#146](https://github.com/gulrak/filesystem/issues/146), handle `EINTR` + on POSIX directory iteration and file copy to avoid errors on network + filesystems * Pull request [#145](https://github.com/gulrak/filesystem/pull/145), fix for Y2038 bug in timeToFILETIME on Windows * Pull request [#144](https://github.com/gulrak/filesystem/pull/144), `fs::copy_file()`