Linux System Calls
System calls provided by the linux kernel are exposed in the C programming language via glibc. When a system call is used, you are communicating to the OS and on return the OS communicates to you through the parameters that are returned to system call functions (return values).
Stat System Call:
Stat system call is a system call in Linux to check the status of a file such as to check when the file was accessed. The stat() system call actually returns file attributes. The file attributes of an inode are basically returned by Stat() function. An inode contains the metadata of the file. An inode contains: the type of the file, the size of the file, when the file was accessed (modified, deleted) that is time stamps, and the path of the file, the user ID and the group ID, links of the file, and physical address of file content.
We can say that inode contains all the data that is required for the stat() system call and it is the index number for the file which is saved in the inode table. Whenever you create a file an inode number for that file is created. Using stat system call the system tables can be viewed.
Syntax of C Stat system call:
To use the stat system call in C programming language, you have to include the following header file:
Stat is used to get the status of a file. The syntax of C stat system call may not be same for every operating system. In Linux the syntax for stat system call is as follows:
The return type of the function in int, if the function is executed successfully, 0 is returned if there are any errors, -1 will be returned.
Here const char *path specifies the name of the file. If the path of file is a symbolic link then you need to specify the link instead of file name.
Then in the function we have a stat structure in which the data or information about the file is stored which uses a pointer named buf, which is passed in as a paramteter and filled in during the execution of the call and readable by the user after the call.
Stat structure:
The stat structure which is defined in <sys/stat.h> header file contains the following fields:
{
mode_t st_mode;
ino_t st_ino;
dev_t st_dev;
dev_t st_rdev;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
off_t st_size;
struct timspec st_atim;
struct timspec st_mtim;
struct timspec st_ctim;
blksize_t st_blksize;
blkcnt_t st_blocks;
};
Description:
- st_dev: It is the ID of device in which we have our file residing currently.
- st_rdev: This field describes that a particular file represents a particular device.
- st_ino: It is the inode number or the serial number of the file. As it is an index number so it should be unique for all files
- st_size: st_size is the size of the file in bytes.
- st_atime: It is the last time or the recent time at which the file was accessed.
- st_ctime: It is the recent time at which the status or the permissions of the file was changed.
- st_mtime: It is the recent time at which the file was modified.
- st_blksize: This field gives the preferred block size for I/O file system which may vary from file to file.
- st_blocks: This field tells the total number of blocks in multiples of 512 bytes.
- st_nlink: This field tells the total number of hard links.
- st_uid: This field indicates the user ID.
- st_gid: This field indicates the group ID.
- st_mode: It indicates the permissions on the file, tells the modes on a file. Following are the flags that should be defined for st_mode field:
Flags | Description | Flag Value |
---|---|---|
S_IFMT | A bitmask used to get mode value of a file | 0170000 |
S_IFSOCK | A file constant of socket | 0140000 |
S_IFLINK | A file constant of symbolic link | 0120000 |
S_IFREG | File constant for regular file | 0100000 |
S_IFBLK | File constant for block file | 0060000 |
S_IFDIR | File constant for directory file | 0040000 |
S_IFCHR | File constant for character file | 0020000 |
S_IFIFO | A file constant of fifo | 0010000 |
S_ISUID | Set User ID bit | 0004000 |
S_ISGID | Set Group ID bit | 0002000 |
S_ISVTX | Sticky bit which indicates shared text | 0001000 |
S_IRWXU | Owner Permissions (read, write, execute) | 00700 |
S_IRUSR | Read Permissions for owner | 00400 |
S_IWUSR | Write Permissions for owner | 00200 |
S_IXUSR | Execute Permissions for owner | 00100 |
S_IRWXG | Group Permissions (read, write, execute) | 00070 |
S_IRGRP | Read Permissions for group | 00040 |
S_IWGRP | Write Permissions for group | 00020 |
S_IXGRP | Execute Permissions for group | 00010 |
S_IRWXO | Permissions for others (read, write, execute) | 00007 |
S_IROTH | Read Permissions for others | 00004 |
S_IWOTH | Write Permissions for others | 00002 |
S_IXOTH | Execute Permissions for others | 00001 |
How to use Stat system call:
The following example shows how to use stat system call in C programming language in Linux, Ubuntu.
EXAMPLE 1:
In the following code we are going to find the mode of a file:
CODE:
#include<sys/stat.h>
int main()
{
//pointer to stat struct
struct stat sfile;
//stat system call
stat("stat.c", &sfile);
//accessing st_mode (data member of stat struct)
printf("st_mode = %o", sfile.st_mode);
return 0;
}
Compiling and running the program returns as below:
In this code, we have passed the name of the file in stat system call and then the pointer to stat struct which is sfile. The pointer to stat struct is then used to access st_mode which displays the mode of the file using printf statement.
The header file <sys/stat.h> is used so you can use stat system call. The header file <stdio.h> is the standard input/output library file so that you can use printf or scanf in your C code.
EXAMPLE 2:
In the following code we are going to get information about the file using stat system call:
CODE:
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
void sfile(char const filename[]);
int main(){
ssize_t read;
char* buffer = 0;
size_t buf_size = 0;
printf("Enter the name of a file to check: \n");
read = getline(&buffer, &buf_size, stdin);
if (read <=0 ){
printf("getline failed\n");
exit(1);
}
if (buffer[read-1] == '\n'){
buffer[read-1] = 0;
}
int s=open(buffer,O_RDONLY);
if(s==-1){
printf("File doesn't exist\n");
exit(1);
}
else{
sfile(buffer);
}
free(buffer);
return 0;
}
void sfile(char const filename[]){
struct stat sfile;
if(stat(filename,&sfile)==-1){
printf("Error Occurred\n");
}
//Accessing data members of stat struct
printf("\nFile st_uid %d \n",sfile.st_uid);
printf("\nFile st_blksize %ld \n",sfile.st_blksize);
printf("\nFile st_gid %d \n",sfile.st_gid);
printf("\nFile st_blocks %ld \n",sfile.st_blocks);
printf("\nFile st_size %ld \n",sfile.st_size);
printf("\nFile st_nlink %u \n",(unsigned int)sfile.st_nlink);
printf("\nFile Permissions User\n");
printf((sfile.st_mode & S_IRUSR)? "r":"-");
printf((sfile.st_mode & S_IWUSR)? "w":"-");
printf((sfile.st_mode & S_IXUSR)? "x":"-");
printf("\n");
printf("\nFile Permissions Group\n");
printf((sfile.st_mode & S_IRGRP)? "r":"-");
printf((sfile.st_mode & S_IWGRP)? "w":"-");
printf((sfile.st_mode & S_IXGRP)? "x":"-");
printf("\n");
printf("\nFile Permissions Other\n");
printf((sfile.st_mode & S_IROTH)? "r":"-");
printf((sfile.st_mode & S_IWOTH)? "w":"-");
printf((sfile.st_mode & S_IXOTH)? "x":"-");
printf("\n");
}
OUTPUT:
In the above C code, we have entered the name of file and if the file does not exist then the execution of the program will be stopped. This is demonstrated in the following image:
If our file exists, the function sfile(n) will be called in which we have passed the name of the file. Inside the function, first of all we have used Stat system call, if stat() returns -1 then there must e any error so a message will be printed and execution of program will be stopped.
Then in printf statement we have used the name of function and dot separator to access the data members of stat struct.
Then for the mode of file we have accessed the macros or flags of st_mode. Here logical and operator is used to print the respective modes. We have checked for permissions for user, group, and others for the specified file (file name entered by user).
With this you can see how to use the stat system call from the C programming language to get information from the OS kernel about files. If you have a question feel free tell us via comment section.