2010-10-21 62 views
7

J'ai le code ci-dessous seulement une partie de celui-ci est montré ici et je vérifie si un le type de fichier.Comment savoir si un fichier est un lien?

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

Le problème: la valeur de st_mode obtenue quand je fais un printf("\nMode: %d\n",buf.st_mode); le résultat est 33188.

J'ai testé mon programme avec un type de fichier régulier et un lien symbolique. Dans les deux cas, la sortie était "fichier régulier", c'est-à-dire que le cas du lien symbolique échoue et que je ne comprends pas pourquoi?

+0

La question est un peu floue. Testez-vous un lien symbolique, et le programme dit que c'est un fichier régulier? Quelle est la valeur de buf.st_mode? –

+0

@Gintautas: édité. –

+4

Vous avez besoin de 'lstat()'. 'stat()' suit les liens symboliques et vérifie les fichiers vers lesquels ils pointent. –

Répondre

14

De la page man stat (2):

stat() stats le fichier pointé par chemin et Remplit buf.

lstat() est identique à stat(), sauf que si le chemin est un lien symbolique, le lien lui-même est stat-ed, pas le fichier qu'il se réfère.

En d'autres termes, l'appel stat suivra le lien symbolique vers le fichier cible et récupérer les informations que. Essayez plutôt d'utiliser lstat, il vous donnera l'information pour le lien .


Si vous effectuez les opérations suivantes:

touch junkfile 
ln -s junkfile junklink 

puis compiler et exécuter le programme suivant:

#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; 
} 

vous obtiendrez:

stat says file 
lstat says link 

comme prévu.