I would change the line:
sprintf(buf, "%s/%s", dirName, ent->d_name);
to
if (strcmp(dirname, "/") == 0 )
{
sprintf(buf, "/%s", ent->d_name);
}
else
{
sprintf(buf, "%s/%s", dirName, ent->d_name);
}
That made a difference in my testing.
Also,
if (strcmp(tmppath, filename) == 0)
continue;
will result in a memory leak. I would change that to:
if (strcmp(tmppath, filename) == 0)
{
free(tmppath);
continue;
}
Everything else looks good to me.
Update
It will be good to have a destructor of directoryReader
that will close the open directory.
directoryReader::~directoryReader()
{
if (dir != NULL) closedir(dir);
}
Also, p_getfiles
can be reorganized so that:
You open a directory, gather all the files and sub-directories of the directory, close the directory, and then process the files and subdirectories. That way, you don't have to worry about too many open directories.
You can create an instace of
directoryReader
on the stack instead of on the heap.
Here's a little refactored version of p_getfiles
.
void p_getfiles_and_directories(char const* basepath,
char const* filename, //filename is to ignore
std::vector<std::string>& files,
std::vector<std::string>& directories)
{
// This function does not recurse directories.
// It just returns the file and sub-directories in the given
// basepath.
directoryReader dirr(basepath, S_IFREG | S_IFDIR);
char *tmppath = NULL;
struct stat st;
while ((tmppath = dirr.getNext()) != NULL)
{
if (strcmp(tmppath, filename) == 0)
continue;
if (goodpath(tmppath))
{
stat(tmppath, &st);
if (S_ISDIR(st.st_mode))
{
directories.push_back(tmppath);
}
else if (S_ISREG(st.st_mode))
{
files.push_back(tmppath);
}
}
free(tmppath);
}
}
void p_getfiles(char const* basepath, FILE *f, char const* filename) //filename is to ignore
{
// Get all the files and sub-directories in the given basepath.
std::vector<std::string> files;
std::vector<std::string> directories;
p_getfiles_and_directories(basepath, filename, files, directories);
// Recurse directories.
std::vector<std::string>::iterator iter = directories.begin();
std::vector<std::string>::iterator end = directories.end();
for ( ; iter != end; ++iter )
{
if (strcmp((*iter).c_str(), filename) == 0)
printf("uh oh...\n");
p_getfiles((*iter).c_str(), f, filename);
}
// Process files.
iter = files.begin();
end = files.end();
for ( ; iter != end; ++iter )
{
fprintf(stdout, "%s\n", (*iter).c_str());
}
}