Как выяснить, является ли файл ссылкой? - PullRequest
10 голосов
/ 21 октября 2010

У меня есть код ниже , здесь показана только его часть , и я проверяю, является ли тип файла.

struct stat *buf /* just to show the type buf is*/ 

switch (buf.st_mode & S_IFMT) {
     case S_IFBLK:  printf(" block device\n");            break;
     case S_IFCHR:  printf(" character device\n");        break;
     case S_IFDIR:  printf(" directory\n");               break;
     case S_IFIFO:  printf(" FIFO/pipe\n");               break;
     case S_IFLNK:  printf(" symlink\n");                 break;
     case S_IFREG:  printf(" regular file\n");            break;
     case S_IFSOCK: printf(" socket\n");                  break;
     default:       printf(" unknown?\n");                break;
}

Проблема: значение st_modeполученный, когда я делаю printf("\nMode: %d\n",buf.st_mode);, результат равен 33188.

Я протестировал свою программу с обычным типом файла и символической ссылкой.В обоих случаях вывод был "обычным файлом", т.е. регистр символьных ссылок не работает, и я не понимаю, почему?

1 Ответ

18 голосов
/ 21 октября 2010

Со страницы руководства stat (2):

stat() статистика файла, на который указывает путь, и заполняет buf.

lstat() идентичен stat(), за исключением того, что если путь является символической ссылкой, то указывается сама ссылка, а не файл, на который она ссылается.

Другими словами, вызов stat будет проходить по символической ссылке на целевой файл и извлекать информацию для , которая. Попробуйте вместо этого использовать lstat, это дастВы получите информацию для ссылки.


Если вы выполните следующее:

touch junkfile
ln -s junkfile junklink

, то скомпилируйте и запустите следующую программу:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main (void) {
    struct stat buf;
    int x;

    x = stat ("junklink", &buf);
    if (S_ISLNK(buf.st_mode)) printf (" stat says link\n");
    if (S_ISREG(buf.st_mode)) printf (" stat says file\n");

    x = lstat ("junklink", &buf);
    if (S_ISLNK(buf.st_mode)) printf ("lstat says link\n");
    if (S_ISREG(buf.st_mode)) printf ("lstat says file\n");

    return 0;
}

вы получите:

 stat says file
lstat says link

, как и ожидалось.

...