Skip to content

Latest commit

 

History

History
147 lines (108 loc) · 3.72 KB

stat_system_call.md

File metadata and controls

147 lines (108 loc) · 3.72 KB

stat system call

The stat system call is very useful in knowing the information about the file. The information such as file last access time (read and write), created time, file mode, permissions, file type, file size etc are provided by the stat system call. These are all stored in the struct stat data structure. This we need to pass when calling the stat().

The stat looks like below:

int stat(const char *path, struct stat *s);

include the following header files when using this system call.

  1. <sys/stat.h>
  2. <sys/types.h>
  3. <unistd.h>

stat returns 0 on success. So we should only access the structure returned in the stat call if it returns 0.

The stat data structure would look as the following.

struct stat {
    dev_t st_dev;          // id of the device
    ino_t st_ino;          // inode number
    mode_t st_mode;        // protection
    nlink_t st_nlink;      // number of hardlinks
    uid_t st_uid;          // user id of the owner
    gid_t st_gid;          // group id of the 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 io
    blkcnt_t st_blocks;    // number of 512B blocks allocated
    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
    #define st_mtime st_mtim.tv_sec
    #define st_ctime st_ctim.tv_sec
};

stat data structure taken from the manual page of stat system call

The most common usage of stat is to know if the given file is a regular file or directory.

char *path = "/home/dev/work/test.c"
struct stat s;

if (stat(path, s) < 0) {
    fprintf(stderr, "failed to stat %s\n", s);
    perror("stat:");
    return -1;
}

if (s.st_mode & S_IFREG) {
    fprintf(stderr, "regular file\n");
} else {
    fprintf(stderr, "unknown or un-tested file type\n");
}

Example: basic stat example

Another usage is that the file size without reading the file and counting the number of bytes.

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

int main(int argc, char **argv)
{
    int ret;
    struct stat s;

    if (argc != 2) {
        printf("%s [file name]\n", argv[0]);
        return -1;
    }

    ret = stat(argv[1], &s);
    if (ret) {
        printf("failed to stat: %s\n", strerror(errno));
        return -1;
    }

    printf("file %s size %ld\n", argv[1], s.st_size);
    return 0;
}

The st_atime is changed by file accesses, for ex: read calls.

The st_mtime is changed by file modifications, for ex: write calls.

The st_ctime is changed by writing or by setting inode, for ex: permissions, mode etc.

The below example provides the file's last access time, modification times etc.

#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(int argc, char **argv)
{
    struct stat s;
    int ret;

    if (argc != 2) {
        printf("%s [filename] \n", argv[0]);
        return -1;
    }

    ret = stat(argv[1], &s);
    if (ret) {
        printf("failed to stat %s\n", strerror(errno));
        return -1;
    }


    printf("last accessed: %ld, last modified: %ld, last status changed: %ld\n",
                            s.st_atime,
                            s.st_mtime,
                            s.st_ctime);
    return 0;
}

The stat system call is often used in conjunction with the readdir system call, to find if the path contains a file or a directory.

lstat system call

fstat system call