Nel 2 ° edizione di "The C Programming Language" da Kernighan e Ritchie implementano una versione semplificata del comando UNIX ls
(sezione 8.6 "Esempio - directory listing", p 179).. A tale scopo creano la seguente interfaccia che fornisce un accesso indipendente dal sistema al nome e al numero di inode dei file memorizzati in una directory.Interfaccia K & R per la lettura di directory: struttura DIR superflua?
#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);
Quindi implementano questa interfaccia per i sistemi UNIX versione 7 e System V.
opendir()
utilizza fondamentalmente il sistema chiamataopen()
per aprire una directory emalloc()
allocare spazio per una strutturaDIR
. Il descrittore di file restituito daopen()
viene quindi memorizzato nella variabilefd
di quelloDIR
. Nessun componente è stato memorizzato nel componenteDirent
.readdir()
utilizza la chiamata di sistemaread()
per ottenere la voce successiva directory (dipendente dal sistema) di una directory aperta e copia il modo ottenuto il numero di inode e il nome in unaDirent
struttura statica (ad cui un il puntatore viene restituito). Le informazioni necessarie solo dareaddir()
sono il descrittore di file memorizzato nella strutturaDIR
.
Ora alla mia domanda: Qual è il punto di avere una struttura DIR
? Se la mia comprensione di questo programma è corretta, il componente Dirent
di DIR
non viene mai utilizzato, quindi perché non sostituire l'intera struttura con un descrittore di file e utilizzare direttamente open()
e close()
?
Grazie.
Ps: Sono consapevole che sui moderni sistemi UNIX read()
non è più possibile utilizzare le directory (ho provato questo programma su Ubuntu 10.04), ma voglio comunque assicurarmi di non aver trascurato qualcosa di importante in questo esempio.
La portabilità è stata anche la mia prima ipotesi, ma dopo aver riflettuto su non vedo come 'DIR' potrebbe contribuire a questo. L'unica informazione rilevante che può passare a 'readdir()' è il descrittore del file. Ancora non vedo l'uso del componente 'Dirent' in' DIR'. Indipendentemente dal sistema, qualsiasi implementazione di 'readdir()' può avere un 'Dirent' statico a cui può restituire un puntatore, quindi questo non dovrebbe essere un problema di portabilità. È vero che 'dirwalk()' accede al contenuto di un 'Dirent', ma questo è quello statico di' readdir() ', non quello contenuto in' DIR'. Mi manca qualcosa? – qfab
Ehi, sembra che tu abbia ragione. La mia ipotesi è che iniziarono definendo le loro strutture di dati (con un 'Dirent' all'interno di' DIR') ma finirono per non usarlo. Raggruppare i dati correlati insieme nelle strutture è buono. Un buon esercizio sarebbe quello di riscrivere il codice per fare uso di 'DIR.d' invece di avere' readdir() 'i chiamanti hanno i propri puntatori' Dirent'. – nmichaels
Sì, questa è una spiegazione plausibile. Ma considerando che il libro è stato pubblicato più di 20 anni fa (2a edizione), è strano che qualcosa di simile non sia menzionato nella [errata] (http://cm.bell-labs.com/cm/cs/cbook/ 2ediffs.html). – qfab