C ++ Recursively scanning files / directories with Cygwin
I am looking to write a portable filesystem scanner capable of listing all files in the path to a specific directory recursively.
To do this, I am trying to use cygwin for my compiler using dirent.h and using the template:
#include <dirent.h>
#include <stdio.h>
int main(void)
{
DIR *d;
struct dirent *dir;
d = opendir(".");
if (d)
{
while ((dir = readdir(d)) != NULL)
{
// Stuff
}
closedir(d);
}
return(0);
}
But you also need to add recursive directory search. To do this, my solution was to try opendir () on the following file and judge the error code to determine if it was successfully opened as a directory (which I would then enroll in), or if it was returned as "not a directory" which will then be listed as a file.
I admit that it feels very klugey, but I haven't been able to find a better method that can retain some portability (not win32) even after hours of searching.
So my simplified solution (just psudeo for some) looks something like this:
int scan (string startdir)
{
DIR * d;
struct dirent * dir;
d = opendir (startdir.cstr ());
if (d)
{
while ((dir = readdir (d))! = NULL)
{
if (NOT '.' AND NOT '..')
{
if (temp = opendir (startdir + d) == NULL)
{
// FILE OR ERROR
} else {
// Opened successfully as a directory, so recurse
scan (startdir + d-> d_name + "\\");
}
}
}
closedir (d);
}
return (0);
}
This is just a partially rewritten psuedo code to keep it simple, but it seems to work (although I'm very open to suggestions for better ways to do this).
The main problem I am having is the specific link file c: \ cygwin \ dev \ fd, which seems to open as a directory and recursively open itself indefinitely.
The file "fd" is 4KB, 106 bytes with no extension, and is a shortcut that does not point anywhere in Windows.
This error seems to indicate that either this kludgey method is listening or there is a problem in the cygwin implementation I'm compiling into.
As a quick example:
Error Reading: c: \ cygwin \ dev \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 5 \ fd \ 0 No such file or directory
Excluding this directory, the search works well. But I'm not okay with hardcoding, excluding the scanner.
If anyone has any ideas, suggestions, solutions, or alternative methods for this problem, your input would be appreciated.
Thanks.
a source to share
Apparently it looks like the fd file is referencing / proc /
I do not guarantee that this is true, but I am under the impression that it allows the scanner to recursively loop through its own directory structure.
My efforts with readlink () to solve this problem were promising at first, but I find it with deeper scan levels it becomes unreliable and errors can still occur.
I am now looking into other ways to achieve this functionality (like boost :: filesystem).
a source to share
If you can use boost then consider using boost :: filesystem . The tutorials include a simple ls program that you can easily extend to work recursively. The library also includes methods for asking for file types, which can probably solve your specific problem.
a source to share
In your example, you tried again to use opendir () to determine if something is a file or a directory. You can do this more directly using stat () from "sys / stat.h". This should also be available in cygwin. You can use the macros S_ISREG () and S_ISDIR () to inspect a regular file or directory. Perhaps something like this:
struct stat *buf = new struct stat;
if(!stat(d->d_name, buf))
{
if(S_ISREG(buf->st_mode))
{
std::cout << " File: " << entry->d_name << "\n";
}
if(S_ISDIR(buf->st_mode) &&
Please also note the answer I provided to another question .