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