what is S_IFMT in UNIX system programming?

14,948

S_IFMT is a bit mask for file type (see man stat)

bitwise AND-ing directly with mystat.st_mode (mystat.st_mode & S_IFMT) means to consider only the bits involved to determine the file type (regular file, socket, block or char device, etc.)

doing a bitwise AND of mystat.st_mode with the bitwise negated bitmask (mystat.st_mode & ~S_IFMT) means to ignore the bits explained above, keeping just the ones need to determine file permission (the 9 lines below that command).

Share:
14,948
user3366497
Author by

user3366497

Updated on June 17, 2022

Comments

  • user3366497
    user3366497 almost 2 years

    I am learning system calls and was thus writing a code to implement ls using C language. The code works, but I cannot understand the working of

    val=(mystat.st_mode & ~S_IFMT)
    

    in the code given below? I understand the rest of the code.

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <dirent.h>
    #include <time.h>
    
    int main(int argc, char* argv[])
    {
        DIR *mydir;
        struct dirent *myfile;
        struct stat mystat;
    
        mydir = opendir(argv[1]);
        char buf[512];
        while((myfile = readdir(mydir)) != NULL)
        {
            struct tm *time_stamp=localtime(&mystat.st_mtime);
            sprintf(buf, "%s/%s", argv[1], myfile->d_name);
            stat(buf, &mystat);
            //stat(myfile->d_name, &mystat);   
            mode_t val;
    
            val=(mystat.st_mode & ~S_IFMT);
            (val & S_IRUSR) ? printf("r") : printf("-");
            (val & S_IWUSR) ? printf("w") : printf("-");    
            (val & S_IXUSR) ? printf("x") : printf("-");
            (val & S_IRGRP) ? printf("r") : printf("-");
            (val & S_IWGRP) ? printf("w") : printf("-");
            (val & S_IXGRP) ? printf("x") : printf("-");
            (val & S_IROTH) ? printf("r") : printf("-");
            (val & S_IWOTH) ? printf("w") : printf("-");
            (val & S_IXOTH) ? printf("x") : printf("-");
            printf("\t%d",mystat.st_nlink);
            printf("\t%d",mystat.st_uid);
            printf("\t%d",mystat.st_gid); 
            printf("\t%d",mystat.st_size);
            char buffer[80];
            strftime(buffer,10,"%b",time_stamp);
    
            printf("\t%4d %s %2d ", time_stamp->tm_year+1900,buffer,time_stamp->tm_mday);
            printf(" %s\n", myfile->d_name);
        }
        closedir(mydir);
    }
    
  • user3366497
    user3366497 almost 9 years
    in the next 9 lines we are performing say (val & S_IRUSR) ,where S_IRUSR means 256(100000000),so other bits will automatically get turned off..so what is the need of bitwise anding with ~S_IFMT then and turning those unnecessary bits off?
  • gengisdave
    gengisdave almost 9 years
    mode_t st_mode is defined on 4 byte (16 bits); the upper 4 are used for file type, while the other 12 are used for file mode (where the lower 9 of these 12 are used for file permission); to be sure the upper 4 bits are set to zero, you can do st_mode AND 0000111111111111 which is exactly ~S_IFMT