ref: 67d4033dabed2e864944c8359b8cff1e66339143
parent: bfb2dd3faafead71d389213eed781447aa55d071
author: Fabian Greffrath <[email protected]>
date: Mon Oct 29 05:57:24 EDT 2018
glob: repair for systems without d_type field in struct dirent The d_type field in struct dirent is not mandated by POSIX and is missing e.g. on MinGW where this leads to a failing build. Fall back to using stat() here.
--- a/src/i_glob.c
+++ b/src/i_glob.c
@@ -36,6 +36,39 @@
#ifndef NO_DIRENT_IMPLEMENTATION
+// Only the fields d_name and (as an XSI extension) d_ino are specified
+// in POSIX.1. Other than Linux, the d_type field is available mainly
+// only on BSD systems. The remaining fields are available on many, but
+// not all systems.
+#if defined(_DIRENT_HAVE_D_TYPE)
+static boolean IsDirectory(char *dir, struct dirent *de)
+{
+ return de->d_type == DT_DIR;
+}
+#else
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+static boolean IsDirectory(char *dir, struct dirent *de)
+{
+ char *filename;
+ struct stat sb;
+ int result;
+
+ filename = M_StringJoin(dir, DIR_SEPARATOR_S, de->d_name, NULL);
+ result = stat(filename, &sb);
+ free(filename);
+
+ if (result != 0)
+ {
+ return false;
+ }
+
+ return S_ISDIR(sb.st_mode);
+}
+#endif
+
struct glob_s
{
char *glob;
@@ -126,7 +159,7 @@
{
return NULL;
}
- } while (de->d_type == DT_DIR || !MatchesGlob(de->d_name, glob->glob));
+ } while (IsDirectory(glob->directory, de) || !MatchesGlob(de->d_name, glob->glob));
// Return the fully-qualified path, not just the bare filename.
free(glob->last_filename);