Вопрос: sys / stat S_ISDIR (m) со структурой dirent


Я хочу проверить, является ли файл каталогом, ссылкой или просто обычным файлом. Я прохожу через каталог и сохраняю каждый файл как struct dirent *, Я пытаюсь пройти d_ino в S_ISDIR(m), S_ISLINK(m), или же S_ISREG(m) и независимо от файла, я не получу положительного результата. Поэтому мой вопрос: как я могу использовать S_ISDIR(m) с struct dirent?


3


источник


Ответы:


Когда вы читаете каталог, используя readdir(3), тип файла сохраняется в d_type переменная члена каждой struct dirent вы получаете, а не d_ino член. Вы редко будете заботиться о номере inode.

Однако не все реализации будут иметь достоверные данные для d_type член, поэтому вам может потребоваться позвонить stat(3) или же lstat(3) для каждого файла, чтобы определить его тип файла (используйте lstat если вы заинтересованы в символических ссылках или используете stat если вас интересуют цели символических ссылок), а затем изучите st_mode член, используя S_IS*** макросы.

Типичная итерация каталогов может выглядеть так:

// 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



S_ISDIR (m), S_ISLINK (m) используется против struct stat.st_mode, и не struct dirent, например:

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

0



К сожалению, вы не можете использовать макросы S_IS * с элементами struct dirent, как указано выше. Однако вам не нужно, поскольку член d_type уже имеет эту информацию для вас. Вы можете прямо протестировать его так:

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

В частности, член d_type может содержать:

   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