Riscritta opendir e spiegata dirent
authorSimone Piccardi <piccardi@gnulinux.it>
Sat, 28 Dec 2002 12:47:27 +0000 (12:47 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sat, 28 Dec 2002 12:47:27 +0000 (12:47 +0000)
filedir.tex

index 2ad3679..bb7f8a6 100644 (file)
@@ -396,8 +396,8 @@ direttamente sul suo contenuto.
 Si noti che non si è specificato il comportamento delle funzioni che operano
 con i file descriptor, in quanto la risoluzione del link simbolico viene in
 genere effettuata dalla funzione che restituisce il file descriptor
-(normalmente la \func{open}) e tutte le operazioni seguenti fanno riferimento
-solo a quest'ultimo.
+(normalmente la \func{open}, vedi \secref{sec:file_open}) e tutte le
+operazioni seguenti fanno riferimento solo a quest'ultimo.
 
 Dato che, come indicato in \tabref{tab:file_symb_effect}, funzioni come la
 \func{open} seguono i link simbolici, occorrono funzioni apposite per accedere
@@ -438,12 +438,13 @@ Un caso comune che si pu
 cosiddetti \textit{loop}. La situazione è illustrata in
 \figref{fig:file_link_loop}, che riporta la struttura della directory
 \file{/boot}. Come si vede si è creato al suo interno un link simbolico che
-punta di nuovo a \file{/boot}.\footnote{Questo tipo di loop è stato effettuato
-  per poter permettere a \cmd{grub} (un bootloader in grado di leggere
-  direttamente da vari filesystem il file da lanciare come sistema operativo)
-  di vedere i file in questa directory con lo stesso path con cui verrebbero
-  visti dal sistema operativo, anche se essi si trovano, come è solito, su una
-  partizione separata (e che \cmd{grub} vedrebbe come radice).}
+punta di nuovo a \file{/boot}.\footnote{il loop mostrato in
+  \figref{fig:file_link_loop} è un usato per poter permettere a \cmd{grub} (un
+  bootloader in grado di leggere direttamente da vari filesystem il file da
+  lanciare come sistema operativo) di vedere i file contenuti nella directory
+  \file{/boot} con lo stesso pathname con cui verrebbero visti dal sistema
+  operativo, anche se essi si trovano, come accade spesso, su una partizione
+  separata (che \cmd{grub}, all'avvio, vede come radice).}
 
 Questo può causare problemi per tutti quei programmi che effettuano la
 scansione di una directory senza tener conto dei link simbolici, ad esempio se
@@ -653,18 +654,27 @@ modificati dal valore di \var{umask}.
 \subsection{Accesso alle directory}
 \label{sec:file_dir_read}
 
-Benché le directory siano oggetti del filesystem come tutti gli altri non ha
-senso aprirle come fossero dei file di dati; per questo solo il kernel può
-scrivere direttamente il contenuto di una directory (onde evitare
-inconsistenze all'interno del filesystem), mentre i processi devono creare i
-file usando le apposite funzioni. Può però essere utile potere leggere il
-contenuto di una directory, ad esempio per fare la lista dei file che contiene
-o per delle ricerche.
-
-Per far questo lo standard POSIX\footnote{le funzioni sono previste pure in
-  BSD e SVID.} ha introdotto i cosiddetti \textit{directory streams} (chiamati
-così per l'analogia con i file stream di \capref{cha:files_std_interface}) ed
-una serie di funzioni per la loro gestione. La prima di queste è
+Benché le directory alla fine non siano altro che dei file che contengono
+delle liste di nomi ed inode, per il ruolo che rivestono nella struttura del
+sistema, non possono essere trattate come dei normali file di dati. Ad
+esempio, onde evitare inconsistenze all'interno del filesystem, solo il kernel
+può scrivere il contenuto di una directory, e non può essere un processo a
+inserirvi direttamente delle voci con le usuali funzioni di scrittura. 
+
+Ma se la scrittura e l'aggiornamento dei dati delle directory è compito del
+kernel, sono molte le situazioni in cui i processi necessitano di poterne
+leggere il contenuto. Benché questo possa essere fatto direttamente (vedremo
+in \secref{sec:file_open} che è possibile aprire una directory come se fosse
+un file, anche se solo in sola lettura) in generale il formato con cui esse
+sono scritte può dipendere dal tipo di filesystem, tanto che, come riportato
+in \tabref{tab:file_file_operations}, il VFS del kernel prevede una apposita
+funzione per la lettura delle directory.
+
+Tutto questo si riflette nello standard POSIX\footnote{le funzioni sono
+  previste pure in BSD e SVID.} che ha introdotto una apposita interfaccia per
+la lettura delle directory, basata sui cosiddetti \textit{directory streams}
+(chiamati così per l'analogia con i file stream dell'interfaccia standard di
+\capref{cha:files_std_interface}). La prima funzione di questa interfaccia è
 \funcd{opendir}, il cui prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} \headdecl{dirent.h} 
@@ -680,17 +690,15 @@ una serie di funzioni per la loro gestione. La prima di queste 
 \end{functions}
 
 La funzione apre un \textit{directory stream} per la directory
-\param{dirname}, ritornando il puntatore alla relativa struttura \type{DIR}
-(questo è un tipo opaco\index{tipo!opaco} usato dalle librerie per gestire i
-\textit{directory stream}) da usare per le successive operazioni, posizionando
-lo stream sulla prima voce contenuta nella directory.
+\param{dirname}, ritornando il puntatore ad un oggetto di tipo \type{DIR} (che
+è il tipo opaco\index{tipo!opaco} usato dalle librerie per gestire i
+\textit{directory stream}) da usare per tutte le operazioni successive, la
+funzione inoltre posiziona lo stream sulla prima voce contenuta nella
+directory.
 
 Dato che le directory sono comunque dei file, in alcuni casi può servire
-conoscere il \textit{file descriptor} (tratteremo i \textit{file descriptor}
-in \capref{cha:file_unix_interface}) sottostante un \textit{directory stream},
-ad esempio per utilizzarlo con la funzione \func{fchdir} per cambiare la
-directory di lavoro (vedi \secref{sec:file_work_dir}) a quella relativa allo
-stream stesso. A questo scopo si può usare la funzione \funcd{dirfd}, il cui
+conoscere il \textit{file descriptor} associato ad un \textit{directory
+  stream}, a questo scopo si può usare la funzione \funcd{dirfd}, il cui
 prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} \headdecl{dirent.h} 
@@ -707,7 +715,10 @@ La funzione\footnote{questa funzione 
   POSIX, introdotta con BSD 4.3-Reno; è presente in Linux con le libc5 (a
   partire dalla versione 5.1.2) e con le \acr{glibc}.} restituisce il file
 descriptor associato al \textit{directory stream} \param{dir}, essa è
-disponibile solo definendo \macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE}.
+disponibile solo definendo \macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE}. Di
+solito si utilizza questa funzione in abbinamento alla funzione \func{fchdir}
+per cambiare la directory di lavoro (vedi \secref{sec:file_work_dir}) a quella
+relativa allo stream che si sta esaminando.
 
 La lettura di una voce nella directory viene effettuata attraverso la funzione
 \funcd{readdir}; il suo prototipo è:
@@ -727,10 +738,10 @@ La lettura di una voce nella directory viene effettuata attraverso la funzione
 
 La funzione legge la voce corrente nella directory, posizionandosi sulla voce
 successiva.  I dati vengono memorizzati in una struttura \struct{dirent} (la
-cui definizione è riportata in \figref{fig:file_dirent_struct}). La funzione
-restituisce il puntatore alla struttura; si tenga presente però che questa
-viene sovrascritta tutte le volte che si ripete una lettura sullo stesso
-stream.
+cui definizione in Linux è riportata in \figref{fig:file_dirent_struct}). La
+funzione restituisce il puntatore alla struttura; si tenga presente però che
+quest'ultima viene sovrascritta tutte le volte che si ripete una lettura sullo
+stesso stream.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -751,6 +762,41 @@ struct dirent {
   \label{fig:file_dirent_struct}
 \end{figure}
 
+I vari campi contengono le informazioni relative ai file della directory; il
+solo campo obbligatorio secondo lo standard POSIX è \var{d\_name}, che
+contiene il nome del file nella forma di una stringa terminata da uno zero, la
+cui lunghezza è riportata nel campo \var{d\_reclen}.\footnote{lo standard
+  POSIX non specifica una lunghezza, ma solo un limite \const{NAME\_MAX},
+  anche se di norma il valore massimo per un nome è di 256 byte.}
+
+Il campo \var{d\_ino} contiene il numero di inode cui il file è associato ed
+il campo \var{d\_type} il tipo di file (fifo, directory, link simbolico,
+ecc.). Entrambi questi campi derivano da BSD e non appartengono allo standard;
+la presenza del tipo di file è segnalata dalla macro
+\macro{\_DIRENT\_HAVE\_D\_TYPE}; i possibili valori del campo \var{d\_type}
+sono riportati in \tabref{tab:file_dtype_macro}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{DT\_UNKNOWN} & tipo sconosciuto. \\
+    \const{DT\_REG}     & file normale. \\
+    \const{DT\_DIR}     & directory. \\
+    \const{DT\_FIFO}    & fifo. \\
+    \const{DT\_SOCK}    & socket. \\
+    \const{DT\_CHR}     & dispositivo a caratteri. \\
+    \const{DT\_BLK}     & dispositivo a blocchi. \\
+    \hline    
+  \end{tabular}
+  \caption{Costanti che indicano i vari tipi di file nel campo \var{d\_type}
+    della struttura \struct{dirent}.}
+  \label{tab:file_dtype_macro}
+\end{table}