stat function and stat command Explanation of [inode = index node] in the Linux file: To understand inode, you must understand the disk and [directory entry]. Inode is actually the intermediate material connecting the [directory entry] and the disk. The big circle in the picture represents the hardware disk, and the small circle inside represents a file stored on the disk. The node of [inode = index node] (the structure that carries the node information is: stat, the definition of stat is later) contains:
In the figure below, hello is a normal file, and hello.hard is a hard link to hello. The folder contains the [Directory Item] of each file as shown below. The [Directory Item] contains:
How to view the file's inode? Use the -i option ls -li filename Execution Result:
It is found that the inode (3801352) of hello and hello.hard are the same, which means that only one copy is stored on the disk. How to view directory items? Use emacs or vim to open the directory (lianxi1), as shown in the screenshot below. But I can't see the file's inode. 1. stat function: Get the file attributes of the specified file. The file attributes are stored in the structure stat. #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int stat(const char *pathname, struct stat *statbuf); int fstat(int fd, struct stat *statbuf); int lstat(const char *pathname, struct stat *statbuf); struct stat structure: struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* Inode number */ mode_t st_mode; /* File type and mode */ nlink_t st_nlink; /* Number of hard links */ uid_t st_uid; /* User ID of owner */ gid_t st_gid; /* Group ID of owner */ dev_t st_rdev; /* Device ID (if special file) */ off_t st_size; /* Total size, in bytes */ blksize_t st_blksize; /* Block size for filesystem I/O */ blkcnt_t st_blocks; /* Number of 512B blocks allocated */ /* Since Linux 2.6, the kernel supports nanosecond precision for the following timestamp fields. For the details before Linux 2.6, see NOTES. */ struct timespec st_atim; /* Time of last access */ struct timespec st_mtim; /* Time of last modification */ struct timespec st_ctim; /* Time of last status change */ #define st_atime st_atim.tv_sec /* Backward compatibility */ #define st_mtime st_mtim.tv_sec #define st_ctime st_ctim.tv_sec }; st_dev: device ID, not commonly used
0-2 bits: other user permissions The file type macros are as follows (the numbers below are in octal):
Function to determine the file type, return true, false S_ISREG(stat.st_mode) is it a regular file? S_ISDIR(stat.st_mode) directory? S_ISCHR(stat.st_mode) character device? S_ISBLK(stat.st_mode) block device? S_ISFIFO(m) FIFO (named pipe)? S_ISLNK(stat.st_mode) symbolic link? (Not in POSIX.1-1996.) S_ISSOCK(stat.st_mode) socket? (Not in POSIX.1-1996.) The macros for file permissions are as follows: S_ISUID 04000 set-user-ID bit S_ISGID 02000 set-group-ID bit (see below) S_ISVTX 01000 sticky bit (see below) S_IRWXU 00700 owner has read, write, and execute permission S_IRUSR 00400 owner has read permission S_IWUSR 00200 owner has write permission S_IXUSR 00100 owner has execute permission S_IRWXG 00070 group has read, write, and execute permission S_IRGRP 00040 group has read permission S_IWGRP 00020 group has write permission S_IXGRP 00010 group has execute permission S_IRWXO 00007 others (not in group) have read, write, and execute permission S_IROTH 00004 others have read permission S_IWOTH 00002 others have write permission S_IXOTH 00001 others have execute permission
struct timespec { __kernel_time_t tv_sec; /* seconds */The number of seconds from the current time to 1970.1.1 00:00:00 long tv_nsec; /* nanoseconds *//Nanoseconds (not sure from where to where) }; 1s second = 1000ms millisecond 1ms millisecond = 1000us microsecond 1us microsecond = 1000ns nanosecond pathname: file name Return value: 0 for success; -1 for failure, and error is set Example: statbuf is the structure stat, and we can see that st_mode is a decimal number. st_mode Use gdb to display st_mode, and find that the returned st_mode is a decimal number. Use gdb's [p/o] (o represents octal representation) command to convert the decimal 33204 into octal [0100664]. The first 0 represents octal, and the last three digits [100] represent the file type. From the above description, we can see that [100] represents a normal file, and the last three digits [664] represent the permissions of this file (this user: rw-, group user: rw-, other users: r--). So from st_mode we can know the file type and permission settings (only 16 bits are used, which really saves space, awesome!) st_uid st_gid It is found that st_uid and st_gid are 1000, but how does this 1000 correspond to the user? Checking the /etc/passwd file, it is found that the uid and gid used for ys are both 1000, so they correspond. The stat command corresponds to the stat function, and the execution results are as follows: ys@ys-VirtualBox:~/lianxi1$ stat hello File: hello Size: 11 Blocks: 8 IO Blocks: 4096 regular file Device: 801h/2049d Inode: 3801352 Links: 2 Access: (0764/-rwxrw-r--) Uid: ( 1000/ ys) Gid: ( 1000/ ys) Access: 2019-04-24 17:02:39.199461489 +0800 Modify: 2019-04-24 16:54:16.407461489 +0800 Change: 2019-04-24 17:03:44.927461489 +0800 2. getpwuid function: returns the line with the specified uid in the /etc/passwd file and puts the information of this line into the structure passwd. Although the return value is a pointer, there is no need to call the free function. #include <sys/types.h> #include <pwd.h> struct passwd *getpwnam(const char *name); struct passwd *getpwuid(uid_t uid); struct passwd { char *pw_name; /* username */ char *pw_passwd; /* user password */ uid_t pw_uid; /* user ID */ gid_t pw_gid; /* group ID */ char *pw_gecos; /* user information */ char *pw_dir; /* home directory */ char *pw_shell; /* shell program */ }; 3. getgrgid function: returns the line with the specified gid in the /etc/group file and puts the information of this line into the structure group. Although the return value is a pointer, there is no need to call the free function. #include <sys/types.h> #include <grp.h> struct group *getgrnam(const char *name); struct group *getgrgid(gid_t gid); struct group { char *gr_name; /* group name */ char *gr_passwd; /* group password */ gid_t gr_gid; /* group ID */ char **gr_mem; /* NULL-terminated array of pointers to names of group members */ }; 4. localtime function: pass in st_mtim.tv_sec (the number of seconds from the current time to 1970.1.1 00:00:00) obtained from the stat function to get the structure tm. Although the return value is a pointer, there is no need to call the free function. #include <time.h> struct tm *localtime(const time_t *timep); struct tm { int tm_sec; /* Seconds (0-60) */ int tm_min; /* Minutes (0-59) */ int tm_hour; /* Hours (0-23) */ int tm_mday; /* Day of the month (1-31) */ int tm_mon; /* Month (0-11) */ int tm_year; /* Year - 1900 */ int tm_wday; /* Day of the week (0-6, Sunday = 0) */ int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */ int tm_isdst; /* Daylight saving time */ }; 5. lstat function: When stat encounters a soft link, it will trace back to the source file and penetrate; lstat does not penetrate. Example: Imitate ls -l file #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <pwd.h>//getpwuid #include <stdlib.h> #include <time.h>//localtime #include <grp.h> //getgrgid int main(int argc, char* argv[]){ struct stat sbuf; //stat(argv[1], &sbuf); lstat(argv[1], &sbuf); char str[11] = {0}; memset(str, '-', (sizeof str - 1)); //File type if(S_ISREG(sbuf.st_mode)) str[0] = '-'; if(S_ISDIR(sbuf.st_mode)) str[0] = 'd'; if(S_ISCHR(sbuf.st_mode)) str[0] = 'c'; if(S_ISBLK(sbuf.st_mode)) str[0] = 'b'; if(S_ISFIFO(sbuf.st_mode)) str[0] = 'p'; if(S_ISLNK(sbuf.st_mode)) str[0] = 'l'; if(S_ISSOCK(sbuf.st_mode)) str[0] = 's'; //File permissions for this user if(sbuf.st_mode & S_IRUSR) str[1] = 'r'; if(sbuf.st_mode & S_IWUSR) str[2] = 'w'; if(sbuf.st_mode & S_IXUSR) str[3] = 'x'; //File permissions of this user's group if(sbuf.st_mode & S_IRGRP) str[4] = 'r'; if(sbuf.st_mode & S_IWGRP) str[5] = 'w'; if(sbuf.st_mode & S_IXGRP) str[6] = 'x'; //File permissions for other users if(sbuf.st_mode & S_IROTH) str[7] = 'r'; if(sbuf.st_mode & S_IWOTH) str[8] = 'w'; if(sbuf.st_mode & S_IXOTH) str[9] = 'x'; char ymd[20] = {0}; //Get date and time struct tm* tm = localtime(&sbuf.st_atim.tv_sec); sprintf(ymd, "%2d月%2d %02d:%02d", tm->tm_mon + 1, tm->tm_mday, tm->tm_hour + 1,tm->tm_sec); //-rw-r--r-- 1 ys ys 134 April 25 09:21 st2.c printf("%s %ld %s %s %ld %s %s\n", str, sbuf.st_nlink, getpwuid(sbuf.st_uid)->pw_name, getgrgid(sbuf.st_gid)->gr_name, sbuf.st_size, ymd, argv[1]); return 0; } 6. Access function: Determine the permissions of the user who calls the program for the specified file (readable? writable? executable?) #include <unistd.h> int access(const char *pathname, int mode); example: #include <stdio.h> #include <unistd.h>//access int main(int argc, char* argv[]){ if (access(argv[1], R_OK) == 0) printf("read ok\n"); if (access(argv[1], W_OK) == 0) printf("write ok\n"); if (access(argv[1], X_OK) == 0) printf("exe ok\n"); if (access(argv[1], F_OK) == 0) printf("exists\n"); } First use ls -l to check the permissions of the /usr/include/time.h file. The results are as follows ys@ys-VirtualBox:~/lianxi$ ls -l /usr/include/time.h -rw-r--r-- 1 root root 10360 April 17, 2018 /usr/include/time.h Run the example program as user ys and view the /usr/include/time.h file. The results are as follows. Because time.h belongs to the root user and is [r--] for other users, the following result is obtained. ys@ys-VirtualBox:~/lianxi$ ./ac /usr/include/time.h read ok exists Still execute it with user ys, but add sudo, the result is as follows. The results are the same as those of the root user. Because sudo was added, the root user was programmed. ys@ys-VirtualBox:~/lianxi$ sudo ./ac /usr/include/time.h [sudo] password for ys: read ok write ok exists 7. truncate function: truncate and expand the file size #include <unistd.h> #include <sys/types.h> int truncate(const char *path, off_t length); path: file 8. Link function: create a hard link #include <unistd.h> int link(const char *oldpath, const char *newpath); Return value: Return 0 if successful, -1 if failed, and set errno. 9. Symlink function: create a soft link #include <unistd.h> int symlink(const char *target, const char *linkpath); Return value: Return 0 if successful, -1 if failed, and set errno. 10. readlink function: find the actual file corresponding to the soft link and put the file name into buf. Note: Hard links will not work. #include <unistd.h> ssize_t readlink(const char *pathname, char *buf, size_t bufsiz); Return value: If successful, it returns the number of bytes written to buf; if failed, it returns -1 and sets errno. 11. unlink function: delete soft and hard links, and can also delete files. #include <unistd.h> int unlink(const char *pathname); Return value: Return 0 if successful, -1 if failed, and set errno. There is a special usage: the following open code wants to create a hello file, and then delete it directly with unlink, but it can be written successfully, ret is greater than 0, and after the program is executed, it is found that the hello file is not created. Conclusion: After executing unlink, the count is 0, but it is found that other processes still reference this file. At this point in time, unlink will not delete this file. It will be deleted after this process ends, so the following write code can be written successfully. #include <unistd.h> #include <sys/types.h> #include <stdio.h> #include <sys/stat.h> #include <fcntl.h> int main(){ int fd = open("hello", O_WRONLY | O_CREAT, 0666); unlink("hello"); int ret = write(fd, "aaa", 4); if(ret > 0){ printf("write OK\n"); } } 12. chown function: change the user and group to which the file belongs #include <unistd.h> int chown(const char *pathname, uid_t owner, gid_t group); pathname: file owner: User ID (numeric) /etc/passwd group: group ID (numeric) /etc/group Return value: 0 on success, -1 on failure. 13. rename function: rename #include <stdio.h> int rename(const char *oldpath, const char *newpath); oldpath: the original file name or directory newpath: new file name or directory Return value: 0 on success, -1 on failure. 14. getcwd function: Get the current working directory #include <unistd.h> char *getcwd(char *buf, size_t size); buf: current working directory size: buffer size Return value: Returns the current working directory if successful; returns NULL if failed 15. chdir function: change the working directory of the process #include <unistd.h> int chdir(const char *path); path: target working directory Return value: 0 for success, -1 for failure 16. mkdir function: create a directory #include <sys/stat.h> #include <sys/types.h> int mkdir(const char *pathname, mode_t mode); pathname: target working directory mode: mode & ~umask & 0777 . Note that if you do not have x permissions, you cannot cd into this directory. Return value: 0 for success, -1 for failure 17. rmdir function: delete a directory. The directory must be an empty directory, that is, there are no files in it. #include <unistd.h> int rmdir(const char *pathname); 18. opendir function: open a directory #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name); name: directory name Return value: a pointer to the directory stream 19. readdir function: read directory #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name); dirp: the return value of the opendir function Return value: dirent structure, which can be understood as the "directory entry" mentioned above. NULL means reading to the end or an error. Other than NULL means the contents of the directory entry. 20. closedir function: close directory #include <sys/types.h> #include <dirent.h> int closedir(DIR *dirp); dirp: the return value of the opendir function 21. strerron function: prints out the text information corresponding to errno. #include <string.h> char *strerror(int errnum); The errnum macro is placed in the file: /usr/include/asm-generic/errno.h example: #include <string.h> #include <stdio.h> #include <asm-generic/errno.h> //EDEADLK int main(){ char* buf = strerror(EDEADLK); printf("%s\n", buf); // Resource deadlock avoided } 22. dup and dup2 functions: redirection of file descriptors #include <unistd.h> int dup(int oldfd); int dup2(int oldfd, int newfd); dup: Similar to open, first open a new file descriptor and let the new file descriptor also point to where oldfd points. Returns the newly opened file descriptor if successful; returns -1 if unsuccessful. dup2: first eliminate the pointer to newfd and then let newfd point to the place where oldfd points. Return newfd if successful; return -1 if failed. Example: Call printf twice. The first printf writes the content to the file; the second printf prints the content to the screen. #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(){ int oldfd = dup(STDOUT_FILENO); int fd = open("www", O_WRONLY | O_CREAT, 0666); dup2(fd, STDOUT_FILENO); printf("aaaa\n"); fflush(stdout); int ret = dup2(oldfd, STDOUT_FILENO); //int ret = dup2(oldfd, 6); //perror("dup2:"); printf("reg:%d\n", ret); printf("aaaa\n"); close(fd); } This is the end of this article about the detailed usage of stat function and stat command in Linux. For more relevant Linux stat function and stat command content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: About the correct way to convert time in js when importing excel
>>: How to use the MySQL authorization command grant
This article shares the specific code of JavaScri...
In the previous article, we used Docker to build ...
Docker is divided into CE and EE. The CE version ...
Modify the group to which a user belongs in Linux...
1. Autoflow attribute, if the length and width of...
1. What is SQL injection? Sql injection is an att...
1 Download The address is: https://dev.mysql.com/...
Preface Recently, I encountered such a problem wh...
This article does not have any quibbles, it is jus...
Table of contents Listener 1.watchEffect 2.watch ...
1. Introduction When we log in to MySQL, we often...
1. Problem Sometimes when we log in to Mysql and ...
Docker is equivalent to a container, which can bu...
Table of contents Deploy nginx on server1 Deploy ...
K8s k8s is a cluster. There are multiple Namespac...