C/Unix: How to extract the bits from st_mode?

14,996

I think you are mixing concepts here.

In memory, integer values are always in binary, let's call it native format. st_mode is of type mode_t and that type is an unspecified integer type, probably int.

The concept of base, that is decimal, octal or hexadecimal, is useful only when you covert the number in memory in native format to a text representation, (or back from text to native).

For example:

int x = 42;

assigns the number 42 to the integer variable. Since source code is text, the 42 is input as text, and we know that it is a decimal value (no prefix). But note how we do not specify a base for the variable: it does not have one. This other code:

int x = 0x2A;

is exactly equivalent. Instead of the decimal constant 42 it uses the hexadecimal constant 0x2A, but that is identical, and x got the same value on both cases. Likewise:

int x = 052;

is also equivalent, but with an octal constant.

Now to your code. When you do:

printf("%d", file.st_mode);
33188

you tell the program to output the value of that variable as a decimal number. Remember that printf converts the number from native format to text, so the base of that text matters. If you prefer to see the value as octal, just write:

printf("%o", file.st_mode);
100644

Or in hexadecimal:

printf("%x", file.st_mode);
81A4

The nice thing about octal is that itrepresents exactly 3 bit per octal digit (4 bits per digit for hex.), so with a bit of practise you can see the bits without computations.

For example, your st_mode is 33188 in decimal or 0100644 in octal. The decimal tells me nothing, but the octal does mean something, because I remember that the last 9 bits (3 octal digits) are the permissions: 3 bits for the owner, 3 bits for the group, 3 bits for other. So:

* Owner: 6 that is rw-
* Group: 4 that is r--
* Other: 4 that is r--

BTW, the last 1 is this constant:

#define S_IFREG 0100000

that just means that it is a regular file.

Share:
14,996
Jenna Maiz
Author by

Jenna Maiz

Updated on June 13, 2022

Comments

  • Jenna Maiz
    Jenna Maiz almost 2 years

    I am a beginner to Unix programming and C and I have two questions regarding the struct stat and its field st_mode:

    1. When accessing the st_mode field as below, what type of number is returned( octal, decimal, etc.) ?

      struct stat file;
      stat( someFilePath, &file);
      printf("%d", file.st_mode );
      

    I thought the number is in octal but when I ran this code, and I got the value 33188. What is the base ?

    1. I found out that the st_mode encodes a 16 bit binary number that represents the file type and file permissions. How do I get the 16-bit number from the above output(esp. when it doesn't seem to be in octal). And which parts of the 16-bit digit encodes which information ?

    Thanks for any help.