Detailed description of DIR, dirent,stat and other structures under Linux

Keywords: Programming Unix Linux

First of all, we will talk about the structure of DIR. Following is the definition of the structure of DIR:

  1. struct __dirstream   
  2.    {   
  3.     void *__fd;    
  4.     char *__data;    
  5.     int __entry_data;    
  6.     char *__ptr;    
  7.     int __entry_ptr;    
  8.     size_t __allocation;    
  9.     size_t __size;    
  10.     __libc_lock_define (, __lock)    
  11.    };   
  12.   
  13. typedef struct __dirstream DIR;  

 

The DIR structure, similar to FILE, is an internal structure. The following functions use this internal structure to store information about the directory currently being read (excerpted from) Advanced Programming for UNIX Environment (Second Edition) ) The function DIR *opendir(const char *pathname), which opens the file directory, returns a pointer to the DIR structure, which is used by the following functions:

 

  1. struct dirent *readdir(DIR *dp);   
  2.   
  3. void rewinddir(DIR *dp);   
  4.   
  5. int closedir(DIR *dp);   
  6.   
  7. long telldir(DIR *dp);   
  8.   
  9. void seekdir(DIR *dp,long loc);  

 

As far as DIR structure is concerned, we know so much about it. There is no need to study its members.

Next comes the dirent structure. First, we need to understand the concept of directory file: this file contains the names of other files and pointers to the information related to these files (extract) Advanced Programming for UNIX Environment (Second Edition) ) As can be seen from the definition, dirent points not only to directories, but also to specific files in directories. The readdir function also reads files in directories, which is the evidence. The following is the definition of the dirent structure:

 

  1. struct dirent   
  2. {   
  3.   long d_ino; /* inode number Index Node Number*/  
  4.      
  5.     off_t d_off; /* offset to this dirent Offset in a directory file*/  
  6.      
  7.     unsigned short d_reclen; /* length of this d_name File Name Length*/  
  8.      
  9.     unsigned char d_type; /* the type of d_name File type*/  
  10.      
  11.     char d_name [NAME_MAX+1]; /* file name (null-terminated) File name, up to 255 characters*/  
  12. }  

 

As can be seen from the above definition, the dirent structure stores little information about files, so dirent also plays an index role. If you want to get file information with the effect similar to ls-l, you must rely on the stat function.

The file name read through the readdir function is stored in the d_name member of the structure dirent, while the function

int stat(const char *file_name, struct stat *buf);

The function is to get the details of the file name D d_name and store them in the stat structure. The following is the definition of the stat structure:

 

  1. struct stat {   
  2.   
  3.         mode_t     st_mode;       //File access rights  
  4.   
  5.         ino_t      st_ino;       //Index Node Number  
  6.   
  7.         dev_t      st_dev;        //The device number used in the document  
  8.   
  9.         dev_t      st_rdev;       //Equipment Number of Equipment Documents  
  10.   
  11.         nlink_t    st_nlink;      //Number of hard connections to files  
  12.   
  13.         uid_t      st_uid;        //Owner User Identification Number  
  14.   
  15.         gid_t      st_gid;        //Group identification number  
  16.   
  17.         off_t      st_size;       //File capacity in bytes  
  18.   
  19.         time_t     st_atime;      //The last time the file was accessed  
  20.   
  21.         time_t     st_mtime;      //The last time the file was modified  
  22.   
  23.         time_t     st_ctime;      //The last time to change the state of the file  
  24.   
  25.         blksize_t st_blksize;    //The size of the disk block containing the file  
  26.   
  27.         blkcnt_t   st_blocks;     //The disk block occupied by the file  
  28.   
  29.       };  

 

The information of this record is very detailed, ha ha ha.

Finally, to sum up, what should we do if we want to get detailed information about a directory (e.g. a directory) b file?

First, we use the opendir function to open directory a and return the DIR structure c pointing to directory a.

Next, we call the readdir (c) function to read all files (including directories) under directory a and return the dirent structure d pointing to all files under directory a.

Then, we traverse D and call stat (d - > name, stat * e) to get the details of each file and store them in the stat structure E.

Overall, it is such a process of gradual refinement, in which the three structures play different roles.

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Supplement:
First of all, the internal structure of the sentence "DIR structure is similar to FILE, it is an internal structure" mentioned above is not very clear. Later, I saw an introduction to FILE structure in a blog post, which is as follows:
Bowen address: Click Open Link
"The struct file structure definition is defined in include/linux/fs.h. The file structure represents an open file. Each open file in the system has an associated struct file in the kernel space. It is created by the kernel when the file is opened and passed to any function that operates on the file. After all instances of the file are closed, the kernel releases the data structure. In kernel creation and driver source code, struct A pointer to a file is usually named file or filp."
The FILE structure is created when the kernel opens the file. Referring to the previous code on FILE operation, we can find that when we use FILE structure, we declare a pointer of FILE structure directly, such as:
FILE *fp
Then the fopen function is used to return a FILE structure pointer to fp. We do not declare a structure, but just a pointer to that structure.
So I guess that the specific structure of memory allocation has been completed by the kernel for us.
The use of DIR structure is similar to FILE. In P104 of the Fourth Edition of Linux Programming, there is a program to print all files and directories in a directory. The code is as follows:
  1. #include <unistd.h>  
  2. #include <stdio.h>  
  3. #include <dirent.h>  
  4. #include <string.h>  
  5. #include <sys/stat.h>  
  6. #include <stdlib.h>  
  7.   
  8.   
  9. void printdir(char *dir, int depth)  
  10. {  
  11.     DIR *dp;  
  12.     struct dirent *entry;  
  13.     struct stat statbuf;  
  14.   
  15.     if ((dp = opendir(dir)) == NULL) {  
  16.         fprintf(stderr, "Can`t open directory %s\n", dir);  
  17.         return ;  
  18.     }  
  19.       
  20.     chdir(dir);  
  21.     while ((entry = readdir(dp)) != NULL) {  
  22.         lstat(entry->d_name, &statbuf);  
  23.         if (S_ISDIR(statbuf.st_mode)) {  
  24.             if (strcmp(entry->d_name, ".") == 0 ||   
  25.                 strcmp(entry->d_name, "..") == 0 )    
  26.                 continue;     
  27.             printf("%*s%s/\n", depth, "", entry->d_name);  
  28.             printdir(entry->d_name, depth+4);  
  29.         } else  
  30.             printf("%*s%s\n", depth, "", entry->d_name);  
  31.     }  
  32.     chdir("..");  
  33.     closedir(dp);     
  34. }  
  35.   
  36.   
  37. int main(int argc, char *argv[])  
  38. {  
  39.     char *topdir = ".";  
  40.     if (argc >= 2)  
  41.         topdir = argv[1];  
  42.   
  43.     printf("Directory scan of %s\n", topdir);  
  44.     printdir(topdir, 0);  
  45.     printf("done.\n");  
  46.     exit(0);  
  47. }  

In this program, we only use the DIR structure to declare the pointer of the structure, so the DIR structure should be the same as the FILE structure, when opening a directory, the kernel helps us allocate the memory of the structure.
The same is true of the dirent structure. But the stat structure requires us to declare the structure ourselves.

Posted by squalls_dreams on Sat, 13 Apr 2019 18:27:32 -0700