Skip to content

Commit

Permalink
refs #142, autodetect dirent::d_type and add GHC_OS_SOLARIS detection
Browse files Browse the repository at this point in the history
Took 3 hours 8 minutes
  • Loading branch information
gulrak committed Apr 2, 2022
1 parent f437344 commit c4b507e
Showing 1 changed file with 48 additions and 36 deletions.
84 changes: 48 additions & 36 deletions include/ghc/filesystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -76,7 +78,6 @@
#include <wasi/api.h>
#elif defined(__QNX__)
#define GHC_OS_QNX
#define GHC_NO_DIRENT_D_TYPE
#else
#error "Operating system currently not supported!"
#endif
Expand Down Expand Up @@ -1298,6 +1299,49 @@ 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 <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::unknown;
}

template <typename T>
GHC_INLINE file_type file_type_from_dirent_impl(const T& t, std::true_type)
{
switch (t.d_type) {
case DT_BLK:
return file_type::block;
case DT_CHR:
return file_type::character;
case DT_DIR:
return file_type::directory;
case DT_FIFO:
return file_type::fifo;
case DT_LNK:
return file_type::symlink;
case DT_REG:
return file_type::regular;
case DT_SOCK:
return file_type::socket;
case DT_UNKNOWN:
return file_type::none;
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
} // namespace detail

Expand Down Expand Up @@ -5658,48 +5702,16 @@ class directory_iterator::impl

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<uintmax_t>(-1);
_dir_entry._hard_link_count = static_cast<uintmax_t>(-1);
_dir_entry._last_write_time = 0;
Expand Down

0 comments on commit c4b507e

Please sign in to comment.