- Thread Starter
- #26
i mean i can read man pages like stat(2) but what does this int flags mean? where is this coming from? Confused.
kpa said:The object st is created by the caller ftw(3) and "passed by reference" by using an explicit pointer (the star in front of it in the argument list) to it.
It could be passed by using C++ references, something like this:
Code:int action(const char *path, const struct stat &st, int flags) { std::cout << st.st_uid << " " << st.st_gid << " " << path << "\n"; return 0; }
That would however require a C++ interface to ftw(3) and the stat structure and there's only a C version available.
return ftw("/etc", action, 1);
int (*fn)(const char *, const struct stat *, int)
return ftw("/etc", action, 1);
return ftw("/etc", &action, 1);
kpa said:The second argument of ftw(3) is a pointer to a function that has the following prototype:
Code:int (*fn)(const char *, const struct stat *, int)
The action() function in the above example matches this prototype. It gets called by ftw(3) for every entry the tree walk encounters. This is a common technique called "call back functions" where you can use call different functions based on runtime conditions.
Oh and the following are equivalent because a name of a function is equal to taking the address of the function:
Code:return ftw("/etc", action, 1); return ftw("/etc", &action, 1);
ikbendeman said:I think maybe I'll study dirent.h... I can't get this to traverse /usr/ports and only show directories. I just don't get it and its frustrating me.
// dirtree.cpp
#include <iostream>
#include <ftw.h>
#include <sys/stat.h>
int action(const char *path, const struct stat *st, int flags)
{
if (S_ISDIR(st->st_mode))
std::cout << st->st_uid << " " << st->st_gid << " " << path << "\n";
return 0;
}
int main(int argc, const char *argv[])
{
return ftw("/usr/ports", action, 1);
}
rolfheinrich said:Perhaps using the ftw(3)() interface?
Code:#include <stdio.h> #include <ftw.h> #include <sys/stat.h> int action(const char *path, const struct stat *st, int flags) { printf("%10d%10d %s\n", st->st_uid, st->st_gid, path); return 0; } int main(int argc, const char *argv[]) { return ftw("/etc", action, 16); }
rolfheinrich said:Yeah, in general a computer does not what you want it to do, but it does exactly what you ask it to do
So, why don't you simply ask it to show only directories by using a simple if() statement:
if (S_ISDIR(st->st_mode))
Code:// dirtree.cpp #include <iostream> #include <ftw.h> #include <sys/stat.h> int action(const char *path, const struct stat *st, int flags) { if (S_ISDIR(st->st_mode)) std::cout << st->st_uid << " " << st->st_gid << " " << path << "\n"; return 0; } int main(int argc, const char *argv[]) { return ftw("/usr/ports", action, 1); }
ikbendeman said:seems to me like ftw is not well-enough documented and I'm not the only one who doesn't understand it...
ikbendeman said:There is no output of this code.... seems to me like ftw is not well-enough documented and I'm not the only one who doesn't understand it...
# g++ dirtree.cpp -o dirtree && ./dirtree
0 0 /usr/ports
0 0 /usr/ports/.svn
0 0 /usr/ports/.svn/pristine
0 0 /usr/ports/.svn/pristine/1b
...