d_type
est une optimisation de vitesse pour économiser sur lstat(2)
appels, lorsqu'ils sont pris en charge.
Comme le readdir
(3) la page de manuel indique que tous les systèmes de fichiers ne renvoient pas d'informations réelles dans le d_type
champ (généralement parce qu'il faudrait une recherche de disque supplémentaire pour lire l'inode, comme c'est le cas pour XFS si vous n'utilisiez pas mkfs.xfs -n ftype=1
(sous-entendu par -m crc=1
qui n'est pas encore la valeur par défaut). Systèmes de fichiers qui définissent toujours DT_UNKNOWN
sont courants dans la vraie vie, et non quelque chose que vous pouvez ignorer. XFS n'est pas le seul exemple.
Vous avez toujours besoin d'un code qui reviendra à l'utilisation de lstat
(2) si d_type==DT_UNKNOWN
, si le nom du fichier seul ne suffit pas pour décider qu'il n'est pas intéressant. (C'est le cas pour certains appelants, comme find -name
ou développer des globs comme *.c
, c'est pourquoi readdir
n'entraîne pas la surcharge de le remplir si cela prendrait une lecture de disque supplémentaire.)
Le Linux getdents(2)
La page de manuel contient un exemple de programme qui fait ce que vous essayez de faire, y compris un bloc chained-terary-operator pour décoder le d_type
champ en chaînes de texte. (Comme le soulignent les autres réponses, votre erreur est de l'imprimer en tant que caractère, plutôt que de le comparer à DT_REG
, DT_DIR
, etc.)
Quoi qu'il en soit, les autres réponses couvraient principalement des choses, mais manquaient le détail critique que vous AVEZ BESOIN d'une alternative pour le cas où d_type == DT_UNKNOWN
(0 sous Linux. d_type
est stocké dans ce qui était autrefois un octet de remplissage, jusqu'à Linux 2.6.4).
Pour être portable, votre code doit vérifier que struct dirent
A même un d_type
champ, si vous l'utilisez, ou votre code ne compilera même pas en dehors des systèmes GNU et BSD. (voir readdir(3)
)
J'ai écrit un exemple pour trouver des répertoires avec readdir , en utilisant d_type
avec un repli sur stat
lorsque d_type n'est pas disponible au moment de la compilation, lorsqu'il est DT_UNKNOWN et pour les liens symboliques.
Le d_type
dans la structure de retour donne un nombre pour le type. Vous ne pouvez pas l'imprimer directement car les valeurs utilisées ne sont pas imprimables lorsqu'elles sont interprétées en ASCII (par exemple, elles sont 4 pour les répertoires et 8 pour les fichiers.).
Vous pouvez soit les imprimer sous forme de nombres comme ceci :
printf("%d ", dent->d_type)
Ou comparez-les aux constantes comme DT_DIR
et construisez une sortie significative à partir de cela, comme un type char :
if(dent->type == DT_DIR) type = 'd'
Imprimer d_type
comme un entier comme ceci :
printf("%d ", dent->d_type);
et vous verrez des valeurs significatives.