Game Development Community

PATCH: Directory recursion broken in x86UNIXFileio.cc on reiser

by Todd "zaz" Koeckeritz · in Torque Game Engine · 12/28/2005 (7:59 pm) · 2 replies

On reiser file systems, recurseDumpDirectories() and hasSubDirectory () are broken when run on reiser file systems. This is because they rely on dirent->d_type to be useful, which isn't guaranteed on all file system types.

In my case, under SuSE 9.3 w/ gcc 3.3.5 and glibc 2.3.4, dirent->d_type was always returning 0(zero)/DT_UNKNOWN. I made a patch to work around this by building the full path to the suspected directory and calling Platform::isDirectory() which more portably uses stat() to determine whether or not the filename in question refers to a directory.

Here's the patch done via "cvs -z3 diff -u -w engine/platformX86UNIX/x86UNIXFileio.cc":
Index: engine/platformX86UNIX/x86UNIXFileio.cc
===================================================================
RCS file: /cvs/torque/torque/engine/platformX86UNIX/x86UNIXFileio.cc,v
retrieving revision 2.5
diff -u -w -r2.5 x86UNIXFileio.cc
--- engine/platformX86UNIX/x86UNIXFileio.cc     2005/11/23 07:31:56     2.5
+++ engine/platformX86UNIX/x86UNIXFileio.cc     2005/12/29 04:07:07
@@ -1019,7 +1019,21 @@

    while (d = readdir(dip))
      {
-       if (d->d_type & DT_DIR)
+       bool    isDir;
+
+       isDir = false;
+       if (d->d_type == DT_UNKNOWN) {
+          char child [1024];
+          if ((pPath[dStrlen(pPath) - 1] == '/'))
+             dSprintf(child, 1024, "%s%s", pPath, d->d_name);
+          else
+             dSprintf(child, 1024, "%s/%s", pPath, d->d_name);
+          isDir = Platform::isDirectory (child);
+       }
+       else if (d->d_type & DT_DIR)
+          isDir = true;
+
+       if (isDir)
        {
          // Skip the . and .. directories
          if (dStrcmp(d->d_name, ".") == 0 ||
@@ -1088,7 +1102,21 @@

    while (d = readdir(dip))
      {
-       if (d->d_type && DT_DIR)
+       bool    isDir;
+
+       isDir = false;
+       if (d->d_type == DT_UNKNOWN) {
+          char child [1024];
+          if ((Path[dStrlen(Path) - 1] == '/'))
+             dSprintf(child, 1024, "%s%s", Path, d->d_name);
+          else
+             dSprintf(child, 1024, "%s/%s", Path, d->d_name);
+          isDir = Platform::isDirectory (child);
+       }
+       else if (d->d_type & DT_DIR)
+          isDir = true;
+
+       if (isDir)
        {
          if (dStrcmp(d->d_name, ".") == 0 ||
              dStrcmp(d->d_name, "..") == 0)

You may also retrieve the patch for awhile at www.visi.com/~zaz/x86UNIXFileio.cc-dir.patch.

I'll post a pointer in the Linux forum just to make sure the proper set of eyes is aware of this linux specific bug.

EDIT: Minor edits of missing words.

#1
02/22/2006 (12:58 pm)
Just commenting seeing that this is showing up on the answered list ;)

This patch has been tested and integrated into TGE linux 1.4.


-Ron
#2
02/22/2006 (3:36 pm)
Thanks man, I was feeling unappreciated, :-).