C program for reading file information in Linux using “Stat” system call

Stat system call in Linux return information about a file, in the buffer pointed to by buf. No permissions are required on the file itself, but—in the case of stat() (search) permission is required on all of the directories in pathname that lead to the file. stat() retrieve information about the file pointed to by pathname.

A call to stat system api return a stat structure, which contains the following fields:

[bash] struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ mode_t st_mode; /* protection */ 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; /* blocksize 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 }; [/bash]

The declaration of stat system call looks like,

 int stat(const char *pathname, struct stat *buf); 
 $ vim stat_api.c 
[bash] #include <sys/types.h> #include <sys/stat.h> #include <time.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { struct stat sb; if (argc != 2) { fprintf(stderr, "Usage: %s <pathname>\n", argv[0]); exit(EXIT_FAILURE); } if (stat(argv[1], &sb) == -1) { perror("stat"); exit(EXIT_FAILURE); } printf("File type: "); switch (sb.st_mode & S_IFMT) { case S_IFBLK: printf("block device\n"); break; case S_IFCHR: printf("character device\n"); break; case S_IFDIR: printf("directory\n"); break; case S_IFIFO: printf("FIFO/pipe\n"); break; case S_IFLNK: printf("symlink\n"); break; case S_IFREG: printf("regular file\n"); break; case S_IFSOCK: printf("socket\n"); break; default: printf("unknown?\n"); break; } printf("I-node number: %ld\n", (long) sb.st_ino); printf("Mode: %lo (octal)\n", (unsigned long) sb.st_mode); printf("Link count: %ld\n", (long) sb.st_nlink); printf("Ownership: UID=%ld GID=%ld\n", (long) sb.st_uid, (long) sb.st_gid); printf("Preferred I/O block size: %ld bytes\n", (long) sb.st_blksize); printf("File size: %lld bytes\n", (long long) sb.st_size); printf("Blocks allocated: %lld\n", (long long) sb.st_blocks); printf("Last status change: %s", ctime(&sb.st_ctime)); printf("Last file access: %s", ctime(&sb.st_atime)); printf("Last file modification: %s", ctime(&sb.st_mtime)); exit(EXIT_SUCCESS); } [/bash]
 $ gcc -o stat_api stat_api.c 

Now, lets try to get the information about this same C source file, we created above as,

 $ ./stat_api stat_api.c 
File type:                regular file
I-node number:            13899332
Mode:                     100644 (octal)
Link count:               1
Ownership:                UID=1000   GID=1000
Preferred I/O block size: 4096 bytes
File size:                1637 bytes
Blocks allocated:         8
Last status change:       Wed Jul  5 01:37:19 2017
Last file access:         Sun Aug 26 21:56:03 2018
Last file modification:   Thu Oct 22 09:57:58 2015

Reference – http://man7.org/linux/man-pages/man2/stat.2.html

Leave a Comment