C: Check file type. Using lstat () and macros does not work

I use opendir () to open the directory, and then readdir () and lstat () to get statistics for each file in this directory. After this manpage, I wrote code that did not work under, as I thought. It lists all the files in the current directory, but does not print this file like a regular file, symbolic link or directory.

#include <sys/stat.h> #include <sys/types.h> #include <dirent.h> #include <stdio.h> void main(){ char* folder="."; //folder to open DIR* dir_p; struct dirent* dir_element; struct stat file_info; // open directory dir_p=opendir(folder); // show some info for each file in given directory while(dir_element = readdir(dir_p)){ lstat(dir_element->d_name, &file_info); //getting a file stats puts(dir_element->d_name); // show current filename printf("file mode: %d\n", file_info.st_mode); // print what kind of file we are dealing with if (file_info.st_mode == S_IFDIR) puts("|| directory"); if (file_info.st_mode == S_IFREG) puts("|| regular file"); if (file_info.st_mode == S_IFLNK) puts("|| symbolic link"); } } 
+4
source share
3 answers

There are many macros to interpret st_mode , which is more complex than you think. Use them instead of directly probing the field:

 if (S_ISREG(file_info.st_mode)) // file is a regular file else if (S_ISLNK(file_info.st_mode)) // ... 

There are also S_ISDIR , S_ISSOCK and a few more. See, for example, here for information.

+5
source

I know this is many years later, but for posterity you did it wrong:
@alk was right, the st_mode field contains more information, for example, file type, file permissions, etc.
To extract the file type, you perform bitwise in the st_mode field and the file type mask S_IFMT. Then check the result for everything you want. This is exactly what the macros mentioned by @Ernest Friedman-Hill do . Swicth is better suited for comprehensive checking ie

for a simple case:

  if ((file_info.st_mode & S_IFMT)==S_IFDIR) puts("|| directory"); 

for a full check:

  struct stat st; ... switch (st.st_mode & S_IFMT) { case S_IFREG: puts("|| regular file"); break; case S_IFDIR: puts("|| directory"); break; case S_IFCHR: puts("|| character device"); break; case S_IFBLK: puts("|| block device"); break; case S_IFLNK: puts("|| symbolic link"); break; case S_IFIFO: puts("|| pipe"); break; case S_IFSOCK: puts("|| socket"); break; default: puts("|| unknown"); } 
+3
source

The mode contains a lot of information.

Try the following test:

 if (S_ISDIR(file_info.st_mode)) puts("|| directory"); 
+1
source

All Articles