tags:

views:

51

answers:

2

hi, I'm doing simple tests on all files in directory. But from some reason, sometimes, they behave wrongly? What's bad with my code?

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);
}
A: 

You could try checking if only S_IFDIR is set:

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

I see the following defines:

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

I'm not sure about your case but either S_IFDIR is not set or more than one of those bits within the mask 0xF000 are set.

Brian R. Bondy
Artefacto
+2  A: 

You made some mistakes, the most important being to call stat() without checking its return value. I modified your program to this:

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

When I ran it, I got this output:

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

Now I saw that stat was called with a filename of roland, which doesn't exist in my current working directory. You have to prefix the filenames with the directory name.

Your second bug was to allocate a new struct stat everytime but not freeing the memory after use. By default, C++ doesn't have garbage collection, so your program would run out of memory soon.

Roland Illig