Reputation: 3135
I'm writing a program that iterates through a directory tree depth first (similar to the GNU find program) by recursively constructing paths to each file in the tree and stores the relative paths of encountered files. It also collects some statistics about these files. For this purpose I'm using the stat
function.
I've notices that this fails for very deep directory hierarchies, i.e. long file paths, in accordance with stat
's documentation.
Now my question is: what alternative approach could I use here that is guaranteed to work for paths of any length? (I don't need working code, just a rough outline would be sufficient).
Upvotes: 0
Views: 498
Reputation: 213268
As you are traversing, open each directory you traverse.
You can then get information about a file in that directory using fstatat
. The fstatat
function takes an additional parameter, dirfd
. If you pass a handle to an open directory in that parameter, the path is interpreted as relative to that directory.
int fstatat(int dirfd, const char *pathname, struct stat *buf,
int flags);
The basic usage is:
int dirfd = open("directory path", O_RDONLY);
struct stat st;
int r = fstatat(dirfd, "relative file path", &st, 0);
You can, of course, also use openat
instead of open
, as you recurse. And the special value AT_FDCWD
can be passed as dirfd
to refer to the current working directory.
It is easy to get into symlink loops and recurse forever. It is not uncommon to find symlink loops in practice. On my system, /usr/bin/X11
is a symlink to /usr/bin
.
There are easier ways to traverse file hierarchies. Use ftw or fts instead, if you can.
Upvotes: 4