Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sys/stat S_ISDIR(m) with struct dirent

I want to check to see if a file is a directory, link, or just a regular file. I loop through the directory and save each file as struct dirent *. I try to pass d_ino to S_ISDIR(m), S_ISLINK(m), or S_ISREG(m) and regardless of the file, I will not get a positive result. So my question is: how do I use S_ISDIR(m) with struct dirent?

like image 810
Joe Tyman Avatar asked Feb 17 '26 01:02

Joe Tyman


1 Answers

When you read a directory using readdir(3), the file type is stored in the d_type member variable of each struct dirent you receive, not the d_ino member. You rarely will care about the inode number.

However, not all implementations will have valid data for the d_type member, so you may need to call stat(3) or lstat(3) on each file to determine its file type (use lstat if you're interested in symbolic links, or use stat if you're interested in the targets of symbolic links) and then examine the st_mode member using the S_IS*** macros.

A typical directory iteration might look like this:

// Error checking omitted for expository purposes
DIR *dir = opendir(dir_to_read);
struct dirent *entry;

while((entry = readdir(dir)) != NULL)
{
    struct stat st;
    char filename[512];
    snprintf(filename, sizeof(filename), "%s/%s", dir_to_read, entry->d_name);
    lstat(filename, &st);

    if(S_ISDIR(st.st_mode))
    {
        // This directory entry is another directory
    }
    else if(S_ISLINK(st.st_mode))
    {
        // This entry is a symbolic link
    }
    else if(S_ISREG(st.st_mode))
    {
        // This entry is a regular file
    }
    // etc.
}

closedir(dir);
like image 111
Adam Rosenfield Avatar answered Feb 19 '26 14:02

Adam Rosenfield



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!