Improve POSIX compliance in CLI/FileUtils.cpp (#1064)

Some POSIX platforms, such as Haiku and some BSDs, don't supply DT_*
identifiers and the corresponding d_type field in stat. This fixes that
and has been tested to still work on 64-bit Linux as well as 64-bit
Haiku.
This commit is contained in:
Samuel Crow 2023-10-12 07:46:53 -05:00 committed by GitHub
parent 3d4e99fc6c
commit 984336448c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -165,11 +165,14 @@ static bool traverseDirectoryRec(const std::string& path, const std::function<vo
{ {
joinPaths(buf, path.c_str(), data.d_name); joinPaths(buf, path.c_str(), data.d_name);
int type = data.d_type; #if defined(DTTOIF)
int mode = -1; mode_t mode = DTTOIF(data.d_type);
#else
mode_t mode = 0;
#endif
// we need to stat DT_UNKNOWN to be able to tell the type // we need to stat an UNKNOWN to be able to tell the type
if (type == DT_UNKNOWN) if ((mode & S_IFMT) == 0)
{ {
struct stat st = {}; struct stat st = {};
#ifdef _ATFILE_SOURCE #ifdef _ATFILE_SOURCE
@ -181,15 +184,15 @@ static bool traverseDirectoryRec(const std::string& path, const std::function<vo
mode = st.st_mode; mode = st.st_mode;
} }
if (type == DT_DIR || mode == S_IFDIR) if (mode == S_IFDIR)
{ {
traverseDirectoryRec(buf, callback); traverseDirectoryRec(buf, callback);
} }
else if (type == DT_REG || mode == S_IFREG) else if (mode == S_IFREG)
{ {
callback(buf); callback(buf);
} }
else if (type == DT_LNK || mode == S_IFLNK) else if (mode == S_IFLNK)
{ {
// Skip symbolic links to avoid handling cycles // Skip symbolic links to avoid handling cycles
} }