+La presenza di ulteriori campi opzionali è segnalata dalla definizione di
+altrettante macro nella forma \code{\_DIRENT\_HAVE\_D\_XXX} dove \code{XXX} è
+il nome del relativo campo; nel nostro caso sono definite le macro
+\macro{\_DIRENT\_HAVE\_D\_TYPE}, \macro{\_DIRENT\_HAVE\_D\_OFF} e
+\macro{\_DIRENT\_HAVE\_D\_RECLEN}.
+
+\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}
+
+Per quanto riguarda il significato dei campi opzionali, il campo \var{d\_type}
+indica il tipo di file (fifo, directory, link simbolico, ecc.); i suoi
+possibili valori\footnote{fino alla versione 2.1 delle \acr{glibc} questo
+ campo, pur presente nella struttura, non è implementato, e resta sempre al
+ valore \const{DT\_UNKNOWN}.} sono riportati in
+\tabref{tab:file_dtype_macro}; per la conversione da e verso l'analogo valore
+mantenuto dentro il campo \var{st\_mode} di \struct{stat} sono definite anche
+due macro di conversione \macro{IFTODT} e \macro{DTTOIF}:
+\begin{functions}
+ \funcdecl{int IFTODT(mode\_t MODE)} Converte il tipo di file dal formato di
+ \var{st\_mode} a quello di \var{d\_type}.
+
+ \funcdecl{mode\_t DTTOIF(int DTYPE)} Converte il tipo di file dal formato di
+ \var{d\_type} a quello di \var{st\_mode}.
+\end{functions}
+
+Il campo \var{d\_off} contiene invece la posizione della voce successiva della
+directory, mentre il campo \var{d\_reclen} la lunghezza totale della voce
+letta. Con questi due campi diventa possibile, determinando la posizione delle
+varie voci, spostarsi all'interno dello stream usando la funzione
+\func{seekdir},\footnote{sia questa funzione che \func{telldir}, sono
+ estensioni prese da BSD, non previste dallo standard POSIX.} il cui
+prototipo è:
+\begin{prototype}{dirent.h}{void seekdir(DIR *dir, off\_t offset)}
+ Cambia la posizione all'interno di un \textit{directory stream}.
+\end{prototype}
+
+La funzione non ritorna nulla e non segnala errori, è però necessario che il
+valore dell'argomento \param{offset} sia valido per lo stream \param{dir};
+esso pertanto deve essere stato ottenuto o dal valore di \var{d\_off} di
+\struct{dirent} o dal valore restituito dalla funzione \func{telldir}, che
+legge la posizione corrente; il prototipo di quest'ultima è:
+\begin{prototype}{dirent.h}{off\_t telldir(DIR *dir)}
+ Ritorna la posizione corrente in un \textit{directory stream}.
+
+ \bodydesc{La funzione restituisce la posizione corrente nello stream (un
+ numero positivo) in caso di successo, e -1 altrimenti, nel qual caso
+ \var{errno} assume solo il valore di \errval{EBADF}, corrispondente ad un
+ valore errato per \param{dir}.}
+\end{prototype}
+
+La sola funzione di posizionamento nello stream prevista dallo standard POSIX
+è \funcd{rewinddir}, che riporta la posizione a quella iniziale; il suo
+prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h} \headdecl{dirent.h}
+
+ \funcdecl{void rewinddir(DIR *dir)}
+
+ Si posiziona all'inizio di un \textit{directory stream}.
+\end{functions}
+
+
+Una volta completate le operazioni si può chiudere il \textit{directory
+ stream} con la funzione \funcd{closedir}, il cui prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h} \headdecl{dirent.h}
+
+ \funcdecl{int closedir(DIR * dir)}
+
+ Chiude un \textit{directory stream}.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e -1 altrimenti, nel
+ qual caso \var{errno} assume il valore \errval{EBADF}.}
+\end{functions}
+
+A parte queste funzioni di base in BSD 4.3 è stata introdotta un'altra
+funzione che permette di eseguire una scansione completa (con tanto di ricerca
+ed ordinamento) del contenuto di una directory; la funzione è
+\funcd{scandir}\footnote{in Linux questa funzione è stata introdotta fin dalle
+ libc4.} ed il suo prototipo è:
+\begin{prototype}{dirent.h}{int scandir(const char *dir,
+ struct dirent ***namelist, int(*select)(const struct dirent *),
+ int(*compar)(const struct dirent **, const struct dirent **))}
+
+ Esegue una scansione di un \textit{directory stream}.
+
+ \bodydesc{La funzione restituisce in caso di successo il numero di voci
+ trovate, e -1 altrimenti.}
+\end{prototype}
+
+Al solito, per la presenza fra gli argomenti di due puntatori a funzione, il
+prototipo non è molto comprensibile; queste funzioni però sono quelle che
+controllano rispettivamente la selezione di una voce (\param{select}) e
+l'ordinamento di tutte le voci selezionate (\param{compar}).
+
+La funzione legge tutte le voci della directory indicata dall'argomento
+\param{dir}, passando ciascuna di esse come argomento alla funzione di
+\param{select}; se questa ritorna un valore diverso da zero la voce viene
+inserita in una struttura allocata dinamicamente con \func{malloc}, qualora si
+specifichi un valore \val{NULL} per \func{select} vengono selezionate tutte le
+voci. Tutte le voci selezionate vengono poi inserite un una lista (anch'essa
+allocata con \func{malloc}, che viene riordinata tramite \func{qsort} usando
+la funzione \param{compar} come criterio di ordinamento; alla fine l'indirizzo
+della lista ordinata è restituito nell'argomento \param{namelist}.
+
+Per l'ordinamento sono disponibili anche due funzioni predefinite,
+\funcd{alphasort} e \funcd{versionsort}, i cui prototipi sono:
+\begin{functions}
+ \headdecl{dirent.h}
+
+ \funcdecl{int alphasort(const void *a, const void *b)}
+
+ \funcdecl{int versionsort(const void *a, const void *b)}
+
+ Funzioni per l'ordinamento delle voci di \textit{directory stream}.
+
+ \bodydesc{Le funzioni restituiscono un valore minore, uguale o maggiore di
+ zero qualora il primo argomento sia rispettivamente minore, uguale o
+ maggiore del secondo.}
+\end{functions}
+
+La funzione \func{alphasort} deriva da BSD ed è presente in Linux fin dalle
+libc4\footnote{la versione delle libc4 e libc5 usa però come argomenti dei
+ puntatori a delle strutture \struct{dirent}; le glibc usano il prototipo
+ originario di BSD, mostrato anche nella definizione, che prevede puntatori a
+ \ctyp{void}.} e deve essere specificata come argomento \param{compare} per
+ottenere un ordinamento alfabetico (secondo il valore del campo \var{d\_name}
+delle varie voci). Le \acr{glibc} prevedono come estensione\footnote{le glibc,
+ a partire dalla versione 2.1, effettuano anche l'ordinamento alfabetico
+ tenendo conto delle varie localizzazioni, usando \func{strcoll} al posto di
+ \func{strcmp}.} anche \func{versionsort}, che ordina i nomi tenendo conto
+del numero di versione (cioè qualcosa per cui \file{file10} viene comunque
+dopo \func{file4}.)
+
+Un semplice esempio dell'uso di queste funzioni è riportato in
+\figref{fig:file_my_ls}, dove si è riportata la sezione principale di un
+programma che, usando la routine di scansione illustrata in
+\figref{fig:file_dirscan}, stampa i nomi dei file contenuti in una directory e
+la relativa dimensione (in sostanza una versione semplificata del comando
+\cmd{ls}).
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15.6cm}
+ \includecodesample{listati/my_ls.c}
+ \end{minipage}
+ \caption{Esempio di codice per eseguire la lista dei file contenuti in una
+ directory.}
+ \label{fig:file_my_ls}
+\end{figure}
+
+Il programma è estremamente semplice; in \figref{fig:file_my_ls} si è omessa
+la parte di gestione delle opzioni (che prevede solo l'uso di una funzione per
+la stampa della sintassi, anch'essa omessa) ma il codice completo potrà essere
+trovato coi sorgenti allegati nel file \file{myls.c}.
+
+In sostanza tutto quello che fa il programma, dopo aver controllato
+(\texttt{\small 10--13}) di avere almeno un parametro (che indicherà la
+directory da esaminare) è chiamare (\texttt{\small 14}) la funzione
+\func{DirScan} per eseguire la scansione, usando la funzione \code{do\_ls}
+(\texttt{\small 20--26}) per fare tutto il lavoro.
+
+Quest'ultima si limita (\texttt{\small 23}) a chiamare \func{stat} sul file
+indicato dalla directory entry passata come argomento (il cui nome è appunto
+\var{direntry->d\_name}), memorizzando in una opportuna struttura \var{data} i
+dati ad esso relativi, per poi provvedere (\texttt{\small 24}) a stampare il
+nome del file e la dimensione riportata in \var{data}.
+
+Dato che la funzione verrà chiamata all'interno di \func{DirScan} per ogni
+voce presente questo è sufficiente a stampare la lista completa dei file e
+delle relative dimensioni. Si noti infine come si restituisca sempre 0 come
+valore di ritorno per indicare una esecuzione senza errori.