директория тестирования S_ISDIR работает противоречиво - PullRequest
0 голосов
/ 15 мая 2010

Я делаю простые тесты для всех файлов в каталоге. Но почему-то иногда они ведут себя неправильно? Что плохого в моем коде?

using namespace std;

int main() {
 string s = "/home/";
   struct dirent *file;
   DIR *dir = opendir(s.c_str());

   while ((file = readdir(dir)) != NULL){
    struct stat * file_info = new (struct stat);

    stat(file->d_name,file_info);
    if ((file_info->st_mode & S_IFMT) == S_IFDIR)
     cout << "dir" << endl;
    else
     cout << "other" << endl;
   }
   closedir(dir);
}

Ответы [ 2 ]

4 голосов
/ 16 мая 2010

Вы допустили несколько ошибок, наиболее важным из которых является вызов stat() без проверки его возвращаемого значения. Я изменил вашу программу так:

#include <cstdio>
#include <dirent.h>
#include <iostream>
#include <string>
#include <sys/stat.h>

using namespace std;

int main() {
  string s = "/home/";
  struct dirent *file;
  DIR *dir = opendir(s.c_str());

  while ((file = readdir(dir)) != NULL) {
    struct stat file_info;

    if (stat(file->d_name, &file_info) == -1) {
      perror("stat");
      return 1;
    }

    if (S_ISDIR(file_info.st_mode))
      cout << "dir " << file->d_name << endl;
    else
      cout << "other " << file->d_name << endl;
  }
  closedir(dir);
}

Когда я запустил его, я получил такой вывод:

$ ./a.exe
dir .
dir ..
stat: No such file or directory

Теперь я увидел, что stat вызывается с именем файла roland, которого нет в моем текущем рабочем каталоге. Вы должны поставить префикс файлов перед именем каталога.

Вашей второй ошибкой было выделение нового struct stat каждый раз, но не освобождение памяти после использования. По умолчанию в C ++ нет сборки мусора, поэтому вашей программе скоро не хватит памяти.

0 голосов
/ 16 мая 2010

Вы можете попробовать проверить, если установлено только S_IFDIR:

if((statbuf.st_mode & S_IFDIR)  == S_IFDIR)   
{//dir
}

Я вижу следующие определения:

#define _S_IFMT         0xF000          /* file type mask */
#define _S_IFDIR        0x4000          /* directory */
#define _S_IFCHR        0x2000          /* character special */
#define _S_IFIFO        0x1000          /* pipe */
#define _S_IFREG        0x8000          /* regular */
#define _S_IREAD        0x0100          /* read permission, owner */
#define _S_IWRITE       0x0080          /* write permission, owner */
#define _S_IEXEC        0x0040          /* execute/search permission, owner */

Я не уверен в вашем случае, но либо S_IFDIR не установлено, либо установлено более одного из этих битов в маске 0xF000.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...