diff --git a/.cirrus.yml b/.cirrus.yml index 9766476..d786910 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -25,7 +25,7 @@ centos7_task: centos8_task: container: - image: centos:8 + image: quay.io/centos/centos:stream8 install_script: | yum group install -y "Development Tools" curl -L https://github.com/Kitware/CMake/releases/download/v3.16.4/cmake-3.16.4-Linux-x86_64.tar.gz | tar xzvf - -C /usr/local --strip-components 1 diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index e85211b..f50664b 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -110,7 +110,7 @@ jobs: cxx: clang++-5.0 - name: "Windows MSVC 2019" - os: windows-latest + os: windows-2019 build_type: Release packages: ninja generator: "Visual Studio 16 2019" diff --git a/CMakeLists.txt b/CMakeLists.txt index f6b7f54..7886167 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,8 @@ endif() if(CMAKE_CXX_STANDARD LESS 11) message(FATAL_ERROR "CMAKE_CXX_STANDARD is less than 11, ghc::filesystem only works with C++11 and above.") endif() +message(STATUS "System name: ${CMAKE_SYSTEM_NAME}") +message(STATUS "Compiler ID: ${CMAKE_CXX_COMPILER_ID}") message(STATUS "CMAKE_CXX_COMPILE_FEATURES: ${CMAKE_CXX_COMPILE_FEATURES}") add_library(ghc_filesystem INTERFACE) diff --git a/cmake/GhcHelper.cmake b/cmake/GhcHelper.cmake index 8fffae9..ca0f787 100644 --- a/cmake/GhcHelper.cmake +++ b/cmake/GhcHelper.cmake @@ -1,6 +1,5 @@ macro(AddExecutableWithStdFS targetName) - -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)) +if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)) if(APPLE) include_directories(/usr/local/opt/llvm/include) link_directories(/usr/local/opt/llvm/lib) @@ -20,6 +19,9 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND (CMAKE_CXX_COMPILER_VERSION target_link_libraries(${targetName} -stdlib=libc++) endif() endif() + if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") + target_link_libraries(filesystem_test xnet) + endif() target_compile_definitions(${targetName} PRIVATE USE_STD_FS) endif() @@ -29,6 +31,9 @@ if (CMAKE_COMPILER_IS_GNUCXX AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 8.0 O if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0) target_link_libraries(${targetName} -lstdc++fs) endif() + if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") + target_link_libraries(${targetName} xnet) + endif() target_compile_options(${targetName} PRIVATE $<$:-Wa,-mbig-obj>) target_compile_definitions(${targetName} PRIVATE USE_STD_FS) endif() @@ -47,6 +52,9 @@ macro(AddTestExecutableWithStdCpp cppStd) add_executable(filesystem_test_cpp${cppStd} ${ARGN}) set_property(TARGET filesystem_test_cpp${cppStd} PROPERTY CXX_STANDARD ${cppStd}) target_link_libraries(filesystem_test_cpp${cppStd} ghc_filesystem) + if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") + target_link_libraries(filesystem_test_cpp${cppStd} xnet) + 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/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index a319def..4ec6e08 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -67,6 +67,8 @@ #define GHC_OS_WIN32 #elif defined(__CYGWIN__) #define GHC_OS_CYGWIN +#elif defined(__sun) && defined(__SVR4) +#define GHC_OS_SOLARIS #elif defined(__svr4__) #define GHC_OS_SYS5R4 #elif defined(BSD) @@ -76,7 +78,6 @@ #include #elif defined(__QNX__) #define GHC_OS_QNX -#define GHC_NO_DIRENT_D_TYPE #else #error "Operating system currently not supported!" #endif @@ -1298,6 +1299,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); #else GHC_FS_API std::error_code make_system_error(int err = 0); + +template +struct has_d_type : std::false_type{}; + +template +struct has_d_type : std::true_type {}; + +template +GHC_INLINE file_type file_type_from_dirent_impl(const T&, std::false_type) +{ + return file_type::none; +} + +template +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 +GHC_INLINE file_type file_type_from_dirent(const T& t) +{ + return file_type_from_dirent_impl(t, has_d_type{}); +} #endif } // namespace detail @@ -4580,7 +4640,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 (syscall(__NR_utimensat, AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { #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 ec = detail::make_system_error(); } @@ -5658,48 +5718,16 @@ public: 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); - switch (_entry->d_type) { - case DT_BLK: - _dir_entry._symlink_status.type(file_type::block); - break; - case DT_CHR: - _dir_entry._symlink_status.type(file_type::character); - break; - 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) { + auto ft = detail::file_type_from_dirent(*_entry); + _dir_entry._symlink_status.type(ft); + if (ft != file_type::symlink) { _dir_entry._status = _dir_entry._symlink_status; } else { _dir_entry._status.type(file_type::none); _dir_entry._status.permissions(perms::unknown); } -#endif _dir_entry._file_size = static_cast(-1); _dir_entry._hard_link_count = static_cast(-1); _dir_entry._last_write_time = 0; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f9fdd18..22b9a4d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,6 +13,9 @@ if(GHC_COVERAGE) target_compile_options(filesystem_test PUBLIC --coverage) endif() target_link_libraries(filesystem_test PUBLIC ghc_filesystem --coverage) + if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") + target_link_libraries(filesystem_test PUBLIC xnet) + endif() if("cxx_std_17" IN_LIST GHC_FILESYSTEM_TEST_COMPILE_FEATURES) AddTestExecutableWithStdCpp(17 filesystem_test.cpp catch.hpp) endif() @@ -23,6 +26,9 @@ else() message("Generating test runner for normal test...") add_executable(filesystem_test filesystem_test.cpp catch.hpp) target_link_libraries(filesystem_test ghc_filesystem) + if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") + target_link_libraries(filesystem_test xnet) + endif() target_compile_options(filesystem_test PRIVATE $<$:-s DISABLE_EXCEPTION_CATCHING=0> $<$,$>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror> @@ -67,6 +73,9 @@ add_test(multifile_test multifile_test) add_executable(fwd_impl_test fwd_test.cpp impl_test.cpp) target_link_libraries(fwd_impl_test ghc_filesystem) +if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") + target_link_libraries(fwd_impl_test xnet) +endif() target_compile_options(fwd_impl_test PRIVATE $<$:-s DISABLE_EXCEPTION_CATCHING=0> $<$,$>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror> diff --git a/test/filesystem_test.cpp b/test/filesystem_test.cpp index 7fdd0a5..23aeb95 100644 --- a/test/filesystem_test.cpp +++ b/test/filesystem_test.cpp @@ -2163,6 +2163,7 @@ public: fs::path character_path() const { +#ifndef GHC_OS_SOLARIS std::error_code ec; if (fs::exists("/dev/null", ec)) { return "/dev/null"; @@ -2170,6 +2171,7 @@ public: else if (fs::exists("NUL", ec)) { return "NUL"; } +#endif return fs::path(); } fs::path temp_path() const { return _t.path(); }