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?

Was it helpful?

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);
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top