Sys / stat S_ISDIR (m) with dirent structure

I want to check if a file is a directory, link, or just a regular file. I browse the directory and save each file as struct dirent *. I try to transfer d_inoto 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 to use S_ISDIR(m)with struct dirent?

+3
source share
3 answers

When you read a directory with readdir(3), the file type is stored in the d_typemember variable of each struct direntone you get, not in d_ino. You will rarely care about the inode number.

However, not all implementations will have reliable data for a member d_type, so you may need to call stat(3)either lstat(3)in each file to determine its file type (use lstatif you are interested in symbolic links, or use statif you are interested in the purpose of symbolic links) and then look at the element st_mode, using macros S_IS***.

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);
+7
source

S_ISDIR (m), S_ISLINK (m) is used against struct stat.st_mode, not struct dirent. eg:

struct stat sb;
...
stat ("/", &sb);
printf ("%d", S_ISDIR (sb.st_mode));
0
source

Unfortunately, you cannot use S_IS * macros with struct dirent elements, as described above. However, you do not need to, because the d_type member already has this information for you. You can directly test it as follows:

struct dirent someDirEnt;
... //stuff get it filled out
if(someDirEnt.d_type==DT_LNK)
...//whatever you link

In particular, the d_type member may contain:

   DT_BLK      This is a block device.
   DT_CHR      This is a character device.
   DT_DIR      This is a directory.
   DT_FIFO     This is a named pipe (FIFO).
   DT_LNK      This is a symbolic link.
   DT_REG      This is a regular file.
   DT_SOCK     This is a UNIX domain socket.
   DT_UNKNOWN  The file type is unknown.
0
source

All Articles