+Tutto il grosso del lavoro è svolto dalla funzione \myfunc{dir\_scan},
+riportata in fig.~\ref{fig:file_dirscan}. La funzione è volutamente generica e
+permette di eseguire una funzione, passata come secondo argomento, su tutte le
+voci di una directory. La funzione inizia con l'aprire (\texttt{\small
+ 18--22}) uno \textit{stream} sulla directory passata come primo argomento,
+stampando un messaggio in caso di errore.
+
+Il passo successivo (\texttt{\small 23--24}) è cambiare
+\index{directory~di~lavoro} directory di lavoro (vedi
+sez.~\ref{sec:file_work_dir}), usando in sequenza le funzioni \func{dirfd} e
+\func{fchdir} (in realtà si sarebbe potuto usare direttamente \func{chdir} su
+\var{dirname}), in modo che durante il successivo ciclo (\texttt{\small
+ 26--30}) sulle singole voci dello \textit{stream} ci si trovi all'interno
+della directory.\footnote{questo è essenziale al funzionamento della funzione
+ \code{do\_ls}, e ad ogni funzione che debba usare il campo \var{d\_name}, in
+ quanto i nomi dei file memorizzati all'interno di una struttura
+ \struct{dirent} sono sempre relativi alla directory in questione, e senza
+ questo posizionamento non si sarebbe potuto usare \func{stat} per ottenere
+ le dimensioni.}
+
+Avendo usato lo stratagemma di fare eseguire tutte le manipolazioni necessarie
+alla funzione passata come secondo argomento, il ciclo di scansione della
+directory è molto semplice; si legge una voce alla volta (\texttt{\small 26})
+all'interno di una istruzione di \code{while} e fintanto che si riceve una
+voce valida, cioè un puntatore diverso da \val{NULL}, si esegue
+(\texttt{\small 27}) la funzione di elaborazione \var{compare} (che nel nostro
+caso sarà \code{do\_ls}), ritornando con un codice di errore (\texttt{\small
+ 28}) qualora questa presenti una anomalia, identificata da un codice di
+ritorno negativo. Una volta terminato il ciclo la funzione si conclude con la
+chiusura (\texttt{\small 32}) dello \textit{stream}\footnote{nel nostro caso,
+ uscendo subito dopo la chiamata, questo non servirebbe, in generale però
+ l'operazione è necessaria, dato che la funzione può essere invocata molte
+ volte all'interno dello stesso processo, per cui non chiudere i
+ \textit{directory stream} comporterebbe un consumo progressivo di risorse,
+ con conseguente rischio di esaurimento delle stesse.} e la restituzione
+(\texttt{\small 32}) del codice di operazioni concluse con successo.
+
+
+
+\subsection{La directory di lavoro}
+\label{sec:file_work_dir}
+
+\index{directory~di~lavoro|(}
+
+Come accennato in sez.~\ref{sec:proc_fork} a ciascun processo è associata una
+directory nel filesystem,\footnote{questa viene mantenuta all'interno dei dati
+ della sua \kstruct{task\_struct} (vedi fig.~\ref{fig:proc_task_struct}), più
+ precisamente nel campo \texttt{pwd} della sotto-struttura
+ \kstruct{fs\_struct}.} che è chiamata \textsl{directory corrente} o
+\textsl{directory di lavoro} (in inglese \textit{current working directory}).
+La directory di lavoro è quella da cui si parte quando un
+\itindsub{pathname}{relativo} \textit{pathname} è espresso in forma relativa,
+dove il ``\textsl{relativa}'' fa riferimento appunto a questa directory.
+
+Quando un utente effettua il login, questa directory viene impostata alla
+\textit{home directory} del suo account. Il comando \cmd{cd} della shell
+consente di cambiarla a piacere, spostandosi da una directory ad un'altra, il
+comando \cmd{pwd} la stampa sul terminale. Siccome la directory di lavoro
+resta la stessa quando viene creato un processo figlio (vedi
+sez.~\ref{sec:proc_fork}), la directory di lavoro della shell diventa anche la
+directory di lavoro di qualunque comando da essa lanciato.
+
+Dato che è il kernel che tiene traccia per ciascun processo \itindex{inode}
+dell'\textit{inode} della directory di lavoro, per ottenerne il
+\textit{pathname} occorre usare una apposita funzione,
+\funcd{getcwd},\footnote{con Linux \func{getcwd} è una \textit{system call}
+ dalla versione 2.1.9, in precedenza il valore doveva essere ottenuto tramite
+ il filesystem \texttt{/proc} da \procfile{/proc/self/cwd}.} il cui prototipo
+è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{char *getcwd(char *buffer, size\_t size)}
+\fdesc{Legge il \textit{pathname} della directory di lavoro corrente.}
+}
+{La funzione ritorna il puntatore a \param{buffer} in caso di successo e
+ \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] manca il permesso di lettura o di attraversamento su
+ uno dei componenti del \textit{pathname} (cioè su una delle directory
+ superiori alla corrente).
+ \item[\errcode{EINVAL}] l'argomento \param{size} è zero e \param{buffer} non
+ è nullo.
+ \item[\errcode{ENOENT}] la directory di lavoro è stata eliminata.
+ \item[\errcode{ERANGE}] l'argomento \param{size} è più piccolo della
+ lunghezza del \textit{pathname}.
+ \end{errlist}
+ ed inoltre \errcode{EFAULT} nel suo significato generico.}
+\end{funcproto}
+
+La funzione restituisce il \textit{pathname} completo della directory di
+lavoro corrente nella stringa puntata da \param{buffer}, che deve essere
+precedentemente allocata, per una dimensione massima di \param{size}. Il
+buffer deve essere sufficientemente largo da poter contenere il
+\textit{pathname} completo più lo zero di terminazione della stringa. Qualora
+esso ecceda le dimensioni specificate con \param{size} la funzione restituisce
+un errore.
+
+Si può anche specificare un puntatore nullo come
+\param{buffer},\footnote{questa è un'estensione allo standard POSIX.1,
+ supportata da Linux e dalla \acr{glibc}.} nel qual caso la stringa sarà
+allocata automaticamente per una dimensione pari a \param{size} qualora questa
+sia diversa da zero, o della lunghezza esatta del \textit{pathname}
+altrimenti. In questo caso ci si deve ricordare di disallocare la stringa con
+\func{free} una volta cessato il suo utilizzo.
+
+Un uso comune di \func{getcwd} è quello di salvarsi la directory di lavoro
+all'avvio del programma per poi potervi tornare in un tempo successivo, un
+metodo alternativo più veloce, se non si è a corto di file descriptor, è
+invece quello di aprire all'inizio la directory corrente (vale a dire
+``\texttt{.}'') e tornarvi in seguito con \func{fchdir}.
+
+Di questa funzione esiste una versione alternativa per compatibilità
+all'indietro con BSD, \funcm{getwd}, che non prevede l'argomento \param{size}
+e quindi non consente di specificare la dimensione di \param{buffer} che
+dovrebbe essere allocato in precedenza ed avere una dimensione sufficiente
+(per BSD maggiore \const{PATH\_MAX}, che di solito 256 byte, vedi
+sez.~\ref{sec:sys_limits}). Il problema è che su Linux non esiste una
+dimensione superiore per la lunghezza di un \textit{pathname}, per cui non è
+detto che il buffer sia sufficiente a contenere il nome del file, e questa è
+la ragione principale per cui questa funzione è deprecata, e non la tratteremo.
+
+Una seconda funzione usata per ottenere la directory di lavoro è
+\funcm{get\_current\_dir\_name},\footnote{la funzione è una estensione GNU e
+ presente solo nella \acr{glibc}.} che non prende nessun argomento ed è
+sostanzialmente equivalente ad una \code{getcwd(NULL, 0)}, con la differenza
+che se disponibile essa ritorna il valore della variabile di ambiente
+\envvar{PWD}, che essendo costruita dalla shell può contenere un
+\textit{pathname} comprendente anche dei collegamenti simbolici. Usando
+\func{getcwd} infatti, essendo il \textit{pathname} ricavato risalendo
+all'indietro l'albero della directory, si perderebbe traccia di ogni passaggio
+attraverso eventuali collegamenti simbolici.
+
+Per cambiare la directory di lavoro si può usare la funzione di sistema
+\funcd{chdir}, equivalente del comando di shell \cmd{cd}, il cui nome sta
+appunto per \textit{change directory}, il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int chdir(const char *pathname)}
+\fdesc{Cambia la directory di lavoro per \textit{pathname}.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] manca il permesso di ricerca su uno dei componenti
+ di \param{pathname}.
+ \item[\errcode{ENOTDIR}] non si è specificata una directory.
+ \end{errlist}
+ ed inoltre \errval{EFAULT}, \errval{ELOOP}, \errval{EIO},
+ \errval{ENAMETOOLONG}, \errval{ENOENT} e \errval{ENOMEM} nel loro
+ significato generico.}
+\end{funcproto}
+
+La funzione cambia la directory di lavoro in \param{pathname} ed
+ovviamente \param{pathname} deve indicare una directory per la quale si hanno
+i permessi di accesso.
+
+Dato che ci si può riferire ad una directory anche tramite un file descriptor,
+per cambiare directory di lavoro è disponibile anche la funzione di sistema
+\funcd{fchdir}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int fchdir(int fd)}
+\fdesc{Cambia la directory di lavoro per file descriptor.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà i valori \errval{EBADF} o \errval{EACCES} nel loro
+ significato generico.}
+\end{funcproto}
+
+La funzione è identica a \func{chdir}, ma prende come argomento un file
+descriptor \param{fd} invece di un \textit{pathname}. Anche in questo
+caso \param{fd} deve essere un file descriptor valido che fa riferimento ad
+una directory. Inoltre l'unico errore di accesso possibile (tutti gli altri
+sarebbero occorsi all'apertura di \param{fd}), è quello in cui il processo non
+ha il permesso di attraversamento alla directory specificata da \param{fd}.
+
+\index{directory~di~lavoro|)}
+
+
+\subsection{La creazione dei \textsl{file speciali}}
+\label{sec:file_mknod}
+
+\index{file!di~dispositivo|(}
+\index{file!speciali|(}
+
+Finora abbiamo parlato esclusivamente di file, directory e collegamenti
+simbolici, ma in sez.~\ref{sec:file_file_types} abbiamo visto che il sistema
+prevede anche degli altri tipi di file, che in genere vanno sotto il nome
+generico di \textsl{file speciali}, come i file di dispositivo, le fifo ed i
+socket.
+
+La manipolazione delle caratteristiche di questi file speciali, il cambiamento
+di nome o la loro cancellazione può essere effettuata con le stesse funzioni
+che operano sugli altri file, ma quando li si devono creare sono necessarie,
+come per le directory, delle funzioni apposite. La prima di queste è la
+funzione di sistema \funcd{mknod}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/stat.h}
+\fhead{fcntl.h}
+\fhead{unistd.h}
+\fdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)}
+\fdesc{Crea un file speciale sul filesystem.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EEXIST}] \param{pathname} esiste già o è un collegamento
+ simbolico.
+ \item[\errcode{EINVAL}] il valore di \param{mode} non indica un file, una
+ fifo, un socket o un dispositivo.
+ \item[\errcode{EPERM}] non si hanno privilegi sufficienti a creare
+ \itindex{inode} l'\texttt{inode}, o il filesystem su cui si è cercato di
+ creare \param{pathname} non supporta l'operazione.
+ \end{errlist}
+ ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{ELOOP},
+ \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOSPC},
+ \errval{ENOTDIR} e \errval{EROFS} nel loro significato generico.}
+\end{funcproto}
+
+La funzione permette di creare un \itindex{inode} \textit{inode} di tipo
+generico sul filesystem, e viene in genere utilizzata per creare i file di
+dispositivo, ma si può usare anche per creare qualunque tipo di file speciale
+ed anche file regolari. L'argomento \param{mode} specifica sia il tipo di file
+che si vuole creare che i relativi permessi, secondo i valori riportati in
+tab.~\ref{tab:file_mode_flags}, che vanno combinati con un OR aritmetico. I
+permessi sono comunque modificati nella maniera usuale dal valore di
+\itindex{umask} \textit{umask} (si veda sez.~\ref{sec:file_perm_management}).
+
+Per il tipo di file può essere specificato solo uno fra i seguenti valori:
+\const{S\_IFREG} per un file regolare (che sarà creato vuoto),
+\const{S\_IFBLK} per un dispositivo a blocchi, \const{S\_IFCHR} per un
+dispositivo a caratteri, \const{S\_IFSOCK} per un socket e \const{S\_IFIFO}
+per una fifo;\footnote{con Linux la funzione non può essere usata per creare
+ directory o collegamenti simbolici, si dovranno usare le funzioni
+ \func{mkdir} e \func{symlink} a questo dedicate.} un valore diverso
+comporterà l'errore \errcode{EINVAL}. Inoltre \param{pathname} non deve
+esistere, neanche come collegamento simbolico.
+
+Qualora si sia specificato in \param{mode} un file di dispositivo (vale a dire
+o \const{S\_IFBLK} o \const{S\_IFCHR}), il valore di \param{dev} dovrà essere
+usato per indicare a quale dispositivo si fa riferimento, altrimenti il suo
+valore verrà ignorato. Solo l'amministratore può creare un file di
+dispositivo usando questa funzione (il processo deve avere la
+\itindex{capabilities} \textit{capability} \const{CAP\_MKNOD}), ma in
+Linux\footnote{questo è un comportamento specifico di Linux, la funzione non è
+ prevista dallo standard POSIX.1 originale, mentre è presente in SVr4 e
+ 4.4BSD, ma esistono differenze nei comportamenti e nei codici di errore,
+ tanto che questa è stata introdotta in POSIX.1-2001 con una nota che la
+ definisce portabile solo quando viene usata per creare delle fifo, ma
+ comunque deprecata essendo utilizzabile a tale scopo la specifica
+ \func{mkfifo}.} l'uso per la creazione di un file ordinario, di una fifo o
+di un socket è consentito anche agli utenti normali.