Вопрос

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?

Это было полезно?

Решение

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

Другие советы

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

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

Unfortunately you cannot use the S_IS* macros with struct dirent members, as stated above. However you don't need to since the member d_type already has that info for you. You can directly test it like this:

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.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top