I am printing the result of S_ISDIR(info->st_mode)
and S_ISREG(info->st_mode)
over a directory that contains dynamic libraries with .so
extension and the result is quite surprising, S_ISREG
returns 0
while S_ISDIR
returns 1.
I am a bit confused...
The code:
DIR *dir;
if ((dir = opendir (dirname)) != NULL) {
struct dirent *ent;
while ((ent = readdir (dir)) != NULL) {
struct stat info;
stat(ent->d_name, &info);
printf("file: %s, S_ISREG: %d, S_ISDIR: %d", ent->d_name, S_ISREG(info.st_mode), S_ISDIR(info.st_mode));
}
}
closedir(dir);
The output looks like:
file: ., S_ISREG: 0, S_ISDIR: 1
file: zyva.so, S_ISREG: 0, S_ISDIR: 1
file: .gitignore, S_ISREG: 1, S_ISDIR: 0
file: .., S_ISREG: 0, S_ISDIR: 1
file: plugin-app, S_ISREG: 0, S_ISDIR: 1
file: chat.so, S_ISREG: 0, S_ISDIR: 1
plugin-app is also an executable so it's also a regular file...
You didn't check the return value of stat()
. I'll bet if you do so, you find that it failed. In that case, the struct stat
is not filled in, so it just contains uninitialized garbage (or the result of a previous successful call).
Why did it fail? I bet you find that errno == ENOENT
. Note that ent->d_name
only contains the name of the file, not the path, so when you try to stat
it, it's interpreted as a path relative to the current working directory. Unless dirname
is the directory you're already in, you're having stat
look for these files in the wrong place, so it's no wonder they aren't found.
Either chdir(dirname)
before doing your stat
s, or else construct the full path in a separate buffer by prepending dirname/
to the filename (make sure to check the lengths to ensure that you do not overrun your buffer).