How do I print file permissions as a string?

2019-08-14 16:28发布

问题:

I have a mode_t perms variable which stores the permission for a file returned from another function. I need to print the file permissions as a tring, of the form

rw-r--r-- (0644)

but what I get is

r--r--r-- (100644)

How can I get the right permissions? I've tried googling and don't understand what I'm doing wrong. Here's my code:

    void print_perms(mode_t perms)
    {
        printf( (perms & S_IRUSR) ? "r" : "-");
        printf( (perms & S_IWUSR) ? "w" : "-");
        printf( (perms & S_IXUSR) ? "x" : "-");
        printf( (perms & S_IRGRP) ? "r" : "-");
        printf( (perms & S_IWGRP) ? "w" : "-");
        printf( (perms & S_IXGRP) ? "x" : "-");
        printf( (perms & S_IROTH) ? "r" : "-");
        printf( (perms & S_IWOTH) ? "w" : "-");
        printf( (perms & S_IXOTH) ? "x" : "-");
    }
//later
print_perms(permissions);
printf(" (%d)\n", permissions);

回答1:

First, UNIX file permissions are conventionally expressed in octal, corresponding format string is "%o", not "%d". rw-r--r-- is really 0644, but in C language 0644 == 420, for example (the latter is in decimal).

Second, there are more bits used than 9 specified in the code. You actually should say something like

printf(" (%3o)", perms&0777);


回答2:

Please note that in the bitwise checks (those where you print the r, w and x) you only print the permissions you are interested in. When you print the permissions using %d, you print all permissions. Try to check for S_IFREG also. You will see it causes the 'unexpected' 100 in the beginning. In the permissions field, this bit is set to store that this is a 'regular' file.