Finding File Permissions

All files carry with them something called an inode, which contains file data beyond the file’s name and its contents. The inode references the file’s size, its timestamps, and the file type or mode. It’s this file mode that determines how the file is used, which users can access the file, and what can be done with the file when accessed.

File permissions come into play because they grant users read, write, and execute access to a file. If you own the file, you have full access. If you aren’t the owner, you may only be able to read the file — or not access it at all. The execute mode is granted to programs and directories (folders).

In Unix-like operating systems, the file permissions are visible when displaying a long directory listing, such as:

$ ls -l gettysburg.txt 
-rw-r--r-- 1 dang  staff  177 Sep  5  2015 gettysburg.txt

The inode mode, or file permissions, is the first bit of gobbledygook listed: -rw-r--r-- This cryptograph isn’t difficult to read once you know its presentation. Figure 1 illustrates the details.

figure 1 file permissions

Figure 1. File permissions (mode) breakdown. File type followed by three triplets of access types: “r” read, “w” write, and “x” execute, one set for each user type: owner, group, other.

For file type, you often see l (little L) for a symbolic link, d for a directory, or “-” for a regular file. The other three items are clustered into triplets of rwx for read, write, and execute permissions: the first set is for the owner, the file creator; the second set is for a user group; the final set is for users not in the specific group (others).

The shell command chmod is used by the file’s owner to change permissions, a topic I need not bore you with. For C, however, examining a file’s mode and its permissions falls under control of the stat() function, which returns file details, specifically information stored in the inode. This function is prototyped in the sys/stat.h header file:

int stat(const char *restrict path, struct stat *restrict buf);

The first argument, path, is a string representing a pathname or filename. The second argument, buf, is the address (pointer) of a stat structure variable.

In my books, you find the stat() function used to gather a file’s size and timestamp, and for examining a directory. Within the stat structure, however, you can access the st_mode member to divine a file’s mode, including its permissions:

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

int main(int argc, char *argv[])
{
    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 */
    printf("Permission bits: %X\n",fs.st_mode);

    return(0);
}

At Line 19, the stat() function examines the file provided at the command prompt. The fs stat structure’s address is passed to the function as its second argument.

At Line 27, then the fs structure’s st_mode element is output. Here is the result when the program is run on the file gettysburg.txt:

Obtaining permission mode for 'gettysburg.txt':
Permission bits: 81A4

The hexadecimal value 81A4 is obviously less useful than the -rw-r--r-- thing shown earlier, though both are related. To make the st_mode member relevant, you can employ macros and defined constants, which assist in sifting through the binary data. I cover this topic in next week’s Lesson.

Leave a Reply