Interface K & R pour lire les répertoires: structure DIR superflue?

Dans la 2ème édition de “The C Programming Language” de Kernighan et Ritchie, ils implémentent une version simplifiée de la commande UNIX ls (section 8.6 “Exemple – Listing des répertoires” , p. 179). Pour cela, ils créent l’interface suivante qui fournit un access indépendant du système au nom et au numéro d’inode des fichiers stockés dans un répertoire.

 #define NAME_MAX 14 /* longest filename component; */ /* system dependent */ typedef struct { /* portable director-entry */ long ino; /* inode number */ char name[NAME_MAX+1]; /* name + '\0' terminator */ } Dirent; typedef struct { /* minimal DIR: no buffering, etc. */ int fd; /* file descriptor for directory */ Dirent d; /* the directory entry */ } DIR; DIR *opendir(char *dirname); Dirent *readdir(DIR *dfd); void closedir(DIR *dfd); 

Ensuite, ils implémentent cette interface pour les systèmes UNIX version 7 et System V.

Maintenant à ma question : quel est l’intérêt d’avoir une structure DIR ? Si ma compréhension de ce programme est correcte, le composant Dirent de DIR n’est jamais utilisé, alors pourquoi ne pas remplacer la structure entière par un descripteur de fichier et utiliser directement open() et close() ?

Merci.

Ps: Je suis conscient que sur les systèmes UNIX modernes, read() ne peut plus être utilisé sur les répertoires (j’ai essayé ce programme sur Ubuntu 10.04), mais je veux toujours m’assurer que je n’ai pas oublié quelque chose d’important dans cet exemple.

De K & R:

Malheureusement, le format et le contenu précis d’un répertoire ne sont pas les mêmes sur toutes les versions du système. Nous allons donc diviser la tâche en deux parties pour essayer d’isoler les parties non portables. Le niveau externe définit une structure appelée Dirent et trois routines opendir , readdir et closedir pour fournir un access indépendant du système au nom et au numéro d’inode dans une entrée de répertoire.

La raison en est la portabilité. Ils veulent définir une interface capable de survivre sur des systèmes ayant des structures stat ou des open() et des close() non standard différentes. Ils construisent ensuite un tas d’outils réutilisables qui ne sont même pas compatibles avec un système Unix. C’est le but des emballages.

Peut-être que ce n’est pas utilisé car ils ont commencé par définir leurs structures de données (avec un Dirent dans DIR) mais ils ont fini par ne pas l’utiliser. Garder les structures de données regroupées comme cela est une bonne conception.

Il est donc inutile d’allouer de la mémoire pour la structure de Dirent renvoyée par readdir. De cette façon, ils peuvent réutiliser le Dirent entre les appels subsistent à readdir.