Question

In an attempt to create a new directory on every program execution, I wrote the following:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <sstream>

int main(int argc, char *argv[]) {
  std::stringstream ss;
  std::string base = "directory";
  std::string dir;
  int dir_count = 0;
  bool isdir = true;
  while (isdir) {
    ss.str("");
    ss << base << dir_count << "/";
    dir_count++;
    dir = ss.str();
    struct stat mystat;
    stat(dir.c_str(), &mystat);
    if(! S_ISDIR(mystat.st_mode)) {
      isdir = false;
      mkdir(dir.c_str(), 0700);
    }
  }
}

This works if the first directory name is new; otherwise, if S_ISDIR() evaluates to true on the first iteration, it will continue to evaluate as true in all subsequent iterations causing an infinite loop. This, despite changing the checked-for directory name. Am I using stat() incorrectly?

Était-ce utile?

La solution

Yes, you are using stat incorrectly because you aren't checking the return code for errors. If you did you will see that stat is going to fail because a file that doesn't yet exist is not going pass muster (ENOENT) with stat. So stat will fail before you get to the S_ISDIR check.

You want something more along these lines:

    struct stat mystat;
    int ret = stat(dir.c_str(), &mystat);

    if (ret == -1)
        if (errno == ENOENT)
            if ((ret = mkdir(dir.c_str(), 0700)) != -1)
                isdir = false;
            else
            {
                perror("mkdir");
                exit(1);
            }
        else
        {
            perror("stat");
            exit(1);
        }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top