Как распечатать разрешения файлов в виде строки?

У меня есть переменная mode_t perms, которая сохраняет разрешение для файла, возвращенного из другой функции. Мне нужно напечатать разрешения файлов как tring, формы

rw-r--r-- (0644) 

но я получаю

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

Как я могу получить правильные разрешения? Я пробовал погулять и не понимаю, что я делаю неправильно. Вот мой код:

  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); 

    Во-первых, разрешения UNIX-файлов условно выражаются в восьмеричном, соответствующая строка формата – «% o», а не «% d». rw-r – r– действительно 0644 , но, например, на языке C 0644 == 420 (последний находится в десятичной форме).

    Во-вторых, в коде больше бит, чем 9. Вы должны сказать что-то вроде

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

    Обратите внимание, что в побитовых проверках (тех, где вы печатаете r, w и x) вы печатаете только разрешения, которые вас интересуют. Когда вы печатаете разрешения с помощью% d, вы печатаете все разрешения. Попробуйте также проверить S_IFREG. Вы увидите, что оно вызывает «неожиданное» 100 в начале. В поле «Разрешения» этот бит установлен для хранения, что это «обычный» файл.