Examining File Type and Permissions

The value returned as a file’s inode mode is difficult to interpret, as covered in last week’s Lesson. That is, unless you use the macros and defined constants available in the sys/stat.h header file.

Some of these macros are mentioned in my books, specifically when examining a directory listing to determine a file’s type. For example, the following st_mode member macros come in handy:

S_ISDIR, true when the file is a directory
S_ISLNK, true when the file is a symbolic link
S_ISREG, true when the file is a plain ol’ “regular” file

Other macros are available to test for other file types. To view the full list, examine the contents of the sys/stat.h header file. Use the macros in your code to make sense of the stat structure’s st_mode member value. For example:

if( S_ISREG(fs.st_mode) )

The S_ISREG macro is used in an evaluation and returns TRUE when the file is a regular file. The following code performs this test:

2020_05_02-Lesson-a.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

int main(int argc, char *argv[])
{
    const char *filename;
    struct stat fs;
    int r;

    if( argc<2 )
    {
        puts("Filename required");
        exit(1);
    }

    filename = argv[1];
    printf("Obtaining permission mode for '%s':\n",filename);
    r = stat(filename,&fs);
    if( r==-1 )
    {
        fprintf(stderr,"File error\n");
        exit(1);
    }

    /* file permissions are kept in the st_mode member */
    /* The S_ISREG() macro tests for regular files */
    if( S_ISREG(fs.st_mode) )
        puts("Regular file");
    else
        puts("Not a regular file");

    return(0);
}

Here’s a sample run for the file gettysburg.txt:

Obtaining permission mode for 'gettysburg.txt':
Regular file

Further tests can be done to gather info on the file’s permissions. Logical AND comparisons are made with the value stored in the st_mode member to determine the owner, group, and other permissions for read, write, and execute. Figure 1 shows the matrix for these nine defined constants.

Permissions options

Figure 1. Permissions defined constants naming method.

For example, if you want to test read permission for the “other” group, you use the S_IROTH defined constant: R for “read” and “OTH” for the “other” group. Here’s one way to examine this attribute:

if( fs.st_mode & S_IROTH )

When the evaluation above is TRUE, the file in question has read permission for the “other” group, meaning anyone on the system can read the file.

The following code adds to the earlier example, processing the permissions bits stored in the stat structure’s st_mode member:

2020_05_02-Lesson-b.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

int main()
{
    const char filename[] = "gettysburg.txt";
    struct stat fs;
    int r;

    printf("Obtaining permission mode for '%s':\n",filename);
    r = stat(filename,&fs);
    if( r==-1 )
    {
        fprintf(stderr,"File error\n");
        exit(1);
    }

    /* file permissions are kept in the st_mode member */
    /* The S_ISREG() macro tests for regular files */
    if( S_ISREG(fs.st_mode) )
        puts("Regular file");
    else
        puts("Not a regular file");

    printf("Owner permissions: ");
    if( fs.st_mode & S_IRUSR )
        printf("read ");
    if( fs.st_mode & S_IWUSR )
        printf("write ");
    if( fs.st_mode & S_IXUSR )
        printf("execute");
    putchar('\n');

    printf("Group permissions: ");
    if( fs.st_mode & S_IRGRP )
        printf("read ");
    if( fs.st_mode & S_IWGRP )
        printf("write ");
    if( fs.st_mode & S_IXGRP )
        printf("execute");
    putchar('\n');

    printf("Others permissions: ");
    if( fs.st_mode & S_IROTH )
        printf("read ");
    if( fs.st_mode & S_IWOTH )
        printf("write ");
    if( fs.st_mode & S_IXOTH )
        printf("execute");
    putchar('\n');
  
    return(0);
}

(These source code files are available from my Github account: https://github.com/dangookin/C-For-Dummies-Blog.)

Here’s a sample run on the gettysburg.txt file:

Obtaining permission mode for 'gettysburg.txt':
Regular file
Owner permissions: read write
Group permissions: read
Others permissions: read

In next week’s Lesson, I cover how to set permissions for a file.

Leave a Reply