13

Currently I have some code like (condensed and removed a bunch of error checking):

dp = readdir(dir);
if (dp->d_type == DT_DIR) {
}

This works swimmingly on my Linux machine. However on another machine (looks like SunOS, sparc):

SunOS HOST 5.10 Generic_127127-11 sun4u sparc SUNW,Ultra-5_10

I get the following error at compile time:

error: structure has no member named `d_type'
error: `DT_DIR' undeclared (first use in this function)

I thought the dirent.h header was crossplatform (for POSIX machines). Any suggestions.

Alex Gaynor
  • 14,353
  • 9
  • 63
  • 113
  • When I see cross-platform, I tend to assume you mean Windows and possibly OS/2 as well. :-) The answer for just Posix is easy, and someone already gave it. – Omnifarious Feb 04 '10 at 07:39

1 Answers1

19

Ref http://www.nexenta.org/os/Porting_Codefixes:

The struct dirent definition in solaris does not contain the d_type field. You would need to make the changes as follows

if (de->d_type == DT_DIR)
{
   return 0;
}

changes to

struct stat s; /*include sys/stat.h if necessary */
..
..
stat(de->d_name, &s);
if (s.st_mode & S_IFDIR)
{
  return 0;
}

Since stat is also POSIX standard it should be more cross-platform. But you may want to use if ((s.st_mode & S_IFMT) == S_IFDIR) to follow the standard.

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • 9
    Actually POSIX defines a macro for this: `if (S_ISDIR(s.st_mode))`. Also of course you should check that `stat()` is successful first. – mark4o Feb 04 '10 at 16:44
  • Note that fstatat (2) might be more preferable over stat (2), because `de->d_name` is relative to the opened directory. –  Oct 01 '17 at 19:15
  • I looked into using fstatat() and it requires a file descriptor to the directory being read. That doesn't seem to be a reasonable solution. – codeDr Apr 18 '19 at 17:37