d_type
es una optimización de velocidad para ahorrar en lstat(2)
llamadas, cuando es compatible.
Como el readdir
(3) la página del manual señala que no todos los sistemas de archivos devuelven información real en el d_type
(generalmente porque se necesitaría una búsqueda de disco adicional para leer el inodo, como es el caso de XFS si no usaste mkfs.xfs -n ftype=1
(implicado por -m crc=1
que aún no es el predeterminado). Sistemas de archivos que siempre establecen DT_UNKNOWN
son comunes en la vida real, y no algo que puedas ignorar. XFS no es el único ejemplo.
Siempre necesita un código que recurra al uso de lstat
(2) si d_type==DT_UNKNOWN
, si el nombre del archivo por sí solo no es suficiente para decidir que no es interesante. (Este es el caso de algunas personas que llaman, como find -name
o globos expansivos como *.c
, por lo que readdir
no incurre en la sobrecarga de llenarlo si necesitara una lectura de disco adicional).
Linux getdents(2)
La página de manual tiene un programa de ejemplo que hace lo que está tratando de hacer, incluido un bloque de operador ternario encadenado para decodificar el d_type
campo en cadenas de texto. (Como señalan las otras respuestas, su error es imprimirlo como un carácter, en lugar de compararlo con DT_REG
, DT_DIR
, etc)
De todos modos, las otras respuestas cubrieron principalmente cosas, pero omitieron el detalle crítico de que NECESITAS una alternativa para el caso cuando d_type == DT_UNKNOWN
(0 en Linux. d_type
se almacena en lo que solía ser un byte de relleno, hasta Linux 2.6.4).
Para ser portátil, su código debe verificar que struct dirent
incluso TIENE un d_type
campo, si lo usa, o su código ni siquiera compilará fuera de los sistemas GNU y BSD. (ver readdir(3)
)
Escribí un ejemplo para encontrar directorios con readdir , usando d_type
con una alternativa a stat
cuando d_type no está disponible en tiempo de compilación, cuando es DT_UNKNOWN y para enlaces simbólicos.
El d_type
en la estructura de retorno da un número para el tipo. No puede imprimir eso directamente porque los valores usados no se pueden imprimir cuando se interpretan como ASCII (por ejemplo, son 4 para directorios y 8 para archivos).
Puede imprimirlos como números como este:
printf("%d ", dent->d_type)
O compáralas con las constantes como DT_DIR
y construya algún resultado significativo a partir de eso, como un tipo char:
if(dent->type == DT_DIR) type = 'd'
Imprimir d_type
como un número entero así:
printf("%d ", dent->d_type);
y verá valores significativos.