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.
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.