Skip to content

Commit c4b507e

Browse files
committed
refs #142, autodetect dirent::d_type and add GHC_OS_SOLARIS detection
Took 3 hours 8 minutes
1 parent f437344 commit c4b507e

File tree

1 file changed

+48
-36
lines changed

1 file changed

+48
-36
lines changed

include/ghc/filesystem.hpp

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
#define GHC_OS_WIN32
6868
#elif defined(__CYGWIN__)
6969
#define GHC_OS_CYGWIN
70+
#elif defined(__sun) && defined(__SVR4)
71+
#define GHC_OS_SOLARIS
7072
#elif defined(__svr4__)
7173
#define GHC_OS_SYS5R4
7274
#elif defined(BSD)
@@ -76,7 +78,6 @@
7678
#include <wasi/api.h>
7779
#elif defined(__QNX__)
7880
#define GHC_OS_QNX
79-
#define GHC_NO_DIRENT_D_TYPE
8081
#else
8182
#error "Operating system currently not supported!"
8283
#endif
@@ -1298,6 +1299,49 @@ GHC_FS_API std::error_code make_error_code(portable_error err);
12981299
GHC_FS_API std::error_code make_system_error(uint32_t err = 0);
12991300
#else
13001301
GHC_FS_API std::error_code make_system_error(int err = 0);
1302+
1303+
template <typename T, typename = int>
1304+
struct has_d_type : std::false_type{};
1305+
1306+
template <typename T>
1307+
struct has_d_type<T, decltype((void)T::d_type, 0)> : std::true_type {};
1308+
1309+
template <typename T>
1310+
GHC_INLINE file_type file_type_from_dirent_impl(const T&, std::false_type)
1311+
{
1312+
return file_type::unknown;
1313+
}
1314+
1315+
template <typename T>
1316+
GHC_INLINE file_type file_type_from_dirent_impl(const T& t, std::true_type)
1317+
{
1318+
switch (t.d_type) {
1319+
case DT_BLK:
1320+
return file_type::block;
1321+
case DT_CHR:
1322+
return file_type::character;
1323+
case DT_DIR:
1324+
return file_type::directory;
1325+
case DT_FIFO:
1326+
return file_type::fifo;
1327+
case DT_LNK:
1328+
return file_type::symlink;
1329+
case DT_REG:
1330+
return file_type::regular;
1331+
case DT_SOCK:
1332+
return file_type::socket;
1333+
case DT_UNKNOWN:
1334+
return file_type::none;
1335+
default:
1336+
return file_type::unknown;
1337+
}
1338+
}
1339+
1340+
template <class T>
1341+
GHC_INLINE file_type file_type_from_dirent(const T& t)
1342+
{
1343+
return file_type_from_dirent_impl(t, has_d_type<T>{});
1344+
}
13011345
#endif
13021346
} // namespace detail
13031347

@@ -5658,48 +5702,16 @@ class directory_iterator::impl
56585702

56595703
void copyToDirEntry()
56605704
{
5661-
#ifdef GHC_NO_DIRENT_D_TYPE
5662-
_dir_entry._symlink_status = file_status();
5663-
_dir_entry._status = file_status();
5664-
#else
56655705
_dir_entry._symlink_status.permissions(perms::unknown);
5666-
switch (_entry->d_type) {
5667-
case DT_BLK:
5668-
_dir_entry._symlink_status.type(file_type::block);
5669-
break;
5670-
case DT_CHR:
5671-
_dir_entry._symlink_status.type(file_type::character);
5672-
break;
5673-
case DT_DIR:
5674-
_dir_entry._symlink_status.type(file_type::directory);
5675-
break;
5676-
case DT_FIFO:
5677-
_dir_entry._symlink_status.type(file_type::fifo);
5678-
break;
5679-
case DT_LNK:
5680-
_dir_entry._symlink_status.type(file_type::symlink);
5681-
break;
5682-
case DT_REG:
5683-
_dir_entry._symlink_status.type(file_type::regular);
5684-
break;
5685-
case DT_SOCK:
5686-
_dir_entry._symlink_status.type(file_type::socket);
5687-
break;
5688-
case DT_UNKNOWN:
5689-
_dir_entry._symlink_status.type(file_type::none);
5690-
break;
5691-
default:
5692-
_dir_entry._symlink_status.type(file_type::unknown);
5693-
break;
5694-
}
5695-
if (_entry->d_type != DT_LNK) {
5706+
auto ft = detail::file_type_from_dirent(*_entry);
5707+
_dir_entry._symlink_status.type(ft);
5708+
if (ft != file_type::symlink) {
56965709
_dir_entry._status = _dir_entry._symlink_status;
56975710
}
56985711
else {
56995712
_dir_entry._status.type(file_type::none);
57005713
_dir_entry._status.permissions(perms::unknown);
57015714
}
5702-
#endif
57035715
_dir_entry._file_size = static_cast<uintmax_t>(-1);
57045716
_dir_entry._hard_link_count = static_cast<uintmax_t>(-1);
57055717
_dir_entry._last_write_time = 0;

0 commit comments

Comments
 (0)