logoISU  

CS456 - Systems Programming

Spring 2026

Displaying ./code/mar18/macrodemo.c

/*

Takes as file, prints out numerical file types
also demonstrating use of macros

man 7 inode has info on the mask values for file permissions

The mode of a file consists of two different parts
0040755 - The left three (004) octal digit represents the file type,
	  The middle digit (0) is the set-group ID bit 
          the right three (755)represent the file permissions

The bitmask for the permissions field is 0777 and to get the permissions from 
the mode you'd do something like below

	st.st_mode & 0777;	


The bitmask for the filetype field can be respresented by S_IFMT or 0170000

The numerical filetypes are represented as follows

           S_IFSOCK   0140000   socket
           S_IFLNK    0120000   symbolic link
           S_IFREG    0100000   regular file
           S_IFBLK    0060000   block device
           S_IFDIR    0040000   directory
           S_IFCHR    0020000   character device
           S_IFIFO    0010000   FIFO

So to get the filetype, you can do this below: 

	st.st_mode & 0170000;	

or you can test for filetypes using the macros found in the inode man page, 
discussed below

these are all octal values, hence the leading 0 in the number, which must be 
included in order to represent octal values in C

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


int main (int argc, char **argv){

	//prints usage statement if file not provided
	if(argc < 2){
		fprintf(stderr, "Usage %s file\n", argv[0]);
		exit(1);
	}


	struct stat st; // this calls the stat structure

	int rt;                   //variable to check the return value for stat
	rt = lstat(argv[1], &st);  //call stat on the file, storing the data in st

	//check return value of rt, 
	if(rt < 0){ 
		perror("Error"); 
		exit(-1);
	}

	//getting numerical filetype
	//we are binary AND'ing the mode with the filetype bitmask to get the filetype
	// note that I could have used S_IFMT instead of the octal value below, as it means the same thing
	mode_t filetype = st.st_mode & 0170000;	

	//getting numerical perms
	//binary AND'ing the mode with 0777 to get the file permissions
	mode_t fileperms = st.st_mode & 0777;

	//printing results
	printf("File Type: %o\nFile Permissions: %o\n", filetype, fileperms);


	// there are several macros available you can use to determine if a file is a certain type
	// all macros take a value for the mode  and return either a 1 or 0 indicating if something 
        // is true or false

	//for regular files, it look like this
	if(S_ISREG(st.st_mode))
		printf("This is a regular file, checked via Macro\n");

	//this means the exact same thing as above, but checked using logical AND
	if((st.st_mode & S_IFMT) & S_IFREG)
		printf("This is a regular file, checked using logical AND\n");

	if(S_ISDIR(st.st_mode))
		printf("This is a directory.\n");


	return 0;

}