+In questo capitolo tratteremo in dettaglio le modalità con cui si gestiscono
+file e directory, iniziando dalle funzioni di libreria che si usano per
+copiarli, spostarli e cambiarne i nomi. Esamineremo poi l'interfaccia che
+permette la manipolazione dei vari attributi di file e directory ed alla fine
+prenderemo in esame la struttura di base del sistema delle protezioni e del
+controllo dell'accesso ai file e le successive estensioni (\textit{Extended
+ Attributes}, ACL, quote disco, \textit{capabilities}). Tutto quello che
+riguarda invece la manipolazione del contenuto dei file è lasciato ai capitoli
+successivi.
+
+
+
+\section{La gestione di file e directory}
+\label{sec:file_dir}
+
+Come già accennato in sez.~\ref{sec:file_filesystem} in un sistema unix-like
+la gestione dei file ha delle caratteristiche specifiche che derivano
+direttamente dall'architettura del sistema. In questa sezione esamineremo le
+funzioni usate per la manipolazione di file e directory, per la creazione di
+link simbolici e diretti, per la gestione e la lettura delle directory.
+
+In particolare ci soffermeremo sulle conseguenze che derivano
+dall'architettura dei filesystem illustrata nel capitolo precedente per quanto
+riguarda il comportamento e gli effetti delle varie funzioni.
+
+
+\subsection{Le funzioni \func{link} e \func{unlink}}
+\label{sec:file_link}
+
+Una caratteristica comune a diversi sistemi operativi è quella di poter creare
+dei nomi fittizi (come gli alias del vecchio MacOS o i collegamenti di Windows
+o i nomi logici del VMS) che permettono di fare riferimento allo stesso file
+chiamandolo con nomi diversi o accedendovi da directory diverse.
+
+Questo è possibile anche in ambiente Unix, dove tali collegamenti sono
+usualmente chiamati \textit{link}; ma data l'architettura del sistema riguardo
+la gestione dei file (ed in particolare quanto trattato in
+sez.~\ref{sec:file_arch_func}) ci sono due metodi sostanzialmente diversi per
+fare questa operazione.
+
+Come spiegato in sez.~\ref{sec:file_filesystem} l'accesso al contenuto di un
+file su disco avviene passando attraverso il suo \itindex{inode}
+\textit{inode}, che è la struttura usata dal kernel che lo identifica
+univocamente all'interno di un singolo filesystem. Il nome del file che si
+trova nella voce di una directory è solo un'etichetta, mantenuta all'interno
+della directory, che viene associata ad un puntatore che fa riferimento al
+suddetto \textit{inode}.
+
+Questo significa che, fintanto che si resta sullo stesso filesystem, la
+realizzazione di un link è immediata, ed uno stesso file può avere tanti nomi
+diversi, dati da altrettante associazioni diverse allo stesso \itindex{inode}
+\textit{inode} effettuate tramite ``etichette'' diverse in directory
+diverse. Si noti anche che nessuno di questi nomi viene ad assumere una
+particolare preferenza o originalità rispetto agli altri, in quanto tutti
+fanno comunque riferimento allo stesso \itindex{inode} \textit{inode}.
+
+Per aggiungere ad una directory una voce che faccia riferimento ad un
+\itindex{inode} \textit{inode} già esistente si utilizza la funzione
+\func{link}; si suole chiamare questo tipo di associazione un collegamento
+diretto, o \textit{hard link}. Il prototipo della funzione è il seguente:
+\begin{prototype}{unistd.h}
+{int link(const char *oldpath, const char *newpath)}
+ Crea un nuovo collegamento diretto.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+ errore nel qual caso \var{errno} viene impostata ai valori:
+ \begin{errlist}
+ \item[\errcode{EXDEV}] i file \param{oldpath} e \param{newpath} non fanno
+ riferimento ad un filesystem montato sullo stesso \textit{mount point}.
+ \item[\errcode{EPERM}] il filesystem che contiene \param{oldpath} e
+ \param{newpath} non supporta i link diretti o è una directory.
+ \item[\errcode{EEXIST}] un file (o una directory) di nome \param{newpath}
+ esiste già.
+ \item[\errcode{EMLINK}] ci sono troppi link al file \param{oldpath} (il
+ numero massimo è specificato dalla variabile \const{LINK\_MAX}, vedi
+ sez.~\ref{sec:sys_limits}).
+ \end{errlist}
+ ed inoltre \errval{EACCES}, \errval{ENAMETOOLONG}, \errval{ENOTDIR},
+ \errval{EFAULT}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP},
+ \errval{ENOSPC}, \errval{EIO}.}
+\end{prototype}
+
+La funzione crea sul \itindex{pathname} \textit{pathname} \param{newpath} un
+collegamento diretto al file indicato da \param{oldpath}. Per quanto detto la
+creazione di un nuovo collegamento diretto non copia il contenuto del file, ma
+si limita a creare una voce nella directory specificata da \param{newpath} e
+ad aumentare di uno il numero di riferimenti al file (riportato nel campo
+\var{st\_nlink} della struttura \struct{stat}, vedi sez.~\ref{sec:file_stat})
+aggiungendo il nuovo nome ai precedenti. Si noti che uno stesso file può
+essere così chiamato con vari nomi in diverse directory.
+
+Per quanto dicevamo in sez.~\ref{sec:file_filesystem} la creazione di un
+collegamento diretto è possibile solo se entrambi i \itindex{pathname}
+\textit{pathname} sono nello stesso filesystem; inoltre il filesystem deve
+supportare i collegamenti diretti (il meccanismo non è disponibile ad esempio
+con il filesystem \acr{vfat} di Windows). In realtà la funzione ha un
+ulteriore requisito, e cioè che non solo che i due file siano sullo stesso
+filesystem, ma anche che si faccia riferimento ad essi sullo stesso
+\textit{mount point}.\footnote{si tenga presente infatti (vedi
+ sez.~\ref{sec:sys_file_config}) che a partire dal kernel 2.4 uno stesso
+ filesystem può essere montato più volte su directory diverse.}
+
+La funzione inoltre opera sia sui file ordinari che sugli altri oggetti del
+filesystem, con l'eccezione delle directory. In alcune versioni di Unix solo
+l'amministratore è in grado di creare un collegamento diretto ad un'altra
+directory: questo viene fatto perché con una tale operazione è possibile
+creare dei \textit{loop} nel filesystem (vedi l'esempio mostrato in
+sez.~\ref{sec:file_symlink}, dove riprenderemo il discorso) che molti programmi
+non sono in grado di gestire e la cui rimozione diventerebbe estremamente
+complicata (in genere per questo tipo di errori occorre far girare il
+programma \cmd{fsck} per riparare il filesystem).
+
+Data la pericolosità di questa operazione e la disponibilità dei link
+simbolici che possono fornire la stessa funzionalità senza questi problemi,
+nel caso di Linux questa capacità è stata completamente disabilitata, e al
+tentativo di creare un link diretto ad una directory la funzione \func{link}
+restituisce l'errore \errcode{EPERM}.
+
+Un ulteriore comportamento peculiare di Linux è quello in cui si crea un
+\textit{hard link} ad un link simbolico. In questo caso lo standard POSIX
+prevederebbe che quest'ultimo venga risolto e che il collegamento sia
+effettuato rispetto al file cui esso punta, e che venga riportato un errore
+qualora questo non esista o non sia un file. Questo era anche il comportamento
+iniziale di Linux ma a partire dai kernel della serie 2.0.x\footnote{per la
+ precisione il comportamento era quello previsto dallo standard POSIX fino al
+ kernel di sviluppo 1.3.56, ed è stato temporaneamente ripristinato anche
+ durante lo sviluppo della serie 2.1.x, per poi tornare al comportamento
+ attuale fino ad oggi (per riferimento si veda
+ \href{http://lwn.net/Articles/293902}
+ {\texttt{http://lwn.net/Articles/293902}}).} è stato adottato un
+comportamento che non segue più lo standard per cui l'\textit{hard link} viene
+creato rispetto al link simbolico, e non al file cui questo punta.
+
+La ragione di questa differenza rispetto allo standard, presente anche in
+altri sistemi unix-like, sono dovute al fatto che un link simbolico può fare
+riferimento anche ad un file non esistente o a una directory, per i quali
+l'\textit{hard link} non può essere creato, per cui la scelta di seguire il
+link simbolico è stata ritenuta una scelta scorretta nella progettazione
+dell'interfaccia. Infatti se non ci fosse il comportamento adottato da Linux
+sarebbe impossibile creare un \textit{hard link} ad un link simbolico, perché
+la funzione lo risolverebbe e l'\textit{hard link} verrebbe creato verso la
+destinazione. Invece evitando di seguire lo standard l'operazione diventa
+possibile, ed anche il comportamento della funzione risulta molto più
+comprensibile. Tanto più che se proprio se si vuole creare un \textit{hard
+ link} rispetto alla destinazione di un link simbolico è sempre possibile
+farlo direttamente.\footnote{ciò non toglie che questo comportamento fuori
+ standard possa causare problemi, come nell'esempio descritto nell'articolo
+ citato nella nota precedente, a programmi che non si aspettano questa
+ differenza rispetto allo standard POSIX.}
+
+La rimozione di un file (o più precisamente della voce che lo referenzia
+all'interno di una directory) si effettua con la funzione \funcd{unlink}; il
+suo prototipo è il seguente:
+\begin{prototype}{unistd.h}{int unlink(const char *pathname)}
+
+ Cancella un file.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso il file non viene toccato. La variabile
+ \var{errno} viene impostata secondo i seguenti codici di errore:
+ \begin{errlist}
+ \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una directory.
+ \footnotemark
+ \item[\errcode{EROFS}] \param{pathname} è su un filesystem montato in sola
+ lettura.
+ \item[\errcode{EISDIR}] \param{pathname} fa riferimento a una directory.
+ \end{errlist}
+ ed inoltre: \errval{EACCES}, \errval{EFAULT}, \errval{ENOENT},
+ \errval{ENOTDIR}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP},
+ \errval{EIO}.}
+\end{prototype}
+
+\footnotetext{questo è un valore specifico ritornato da Linux che non consente
+ l'uso di \func{unlink} con le directory (vedi sez.~\ref{sec:file_remove}).
+ Non è conforme allo standard POSIX, che prescrive invece l'uso di
+ \errcode{EPERM} in caso l'operazione non sia consentita o il processo non
+ abbia privilegi sufficienti.}
+
+La funzione cancella il nome specificato da \param{pathname} nella relativa
+directory e decrementa il numero di riferimenti nel relativo \itindex{inode}
+\textit{inode}. Nel caso di link simbolico cancella il link simbolico; nel
+caso di socket, fifo o file di dispositivo \index{file!di~dispositivo} rimuove
+il nome, ma come per i file i processi che hanno aperto uno di questi oggetti
+possono continuare ad utilizzarlo.
+
+Per cancellare una voce in una directory è necessario avere il permesso di
+scrittura su di essa, dato che si va a rimuovere una voce dal suo contenuto, e
+il diritto di esecuzione sulla directory che la contiene (affronteremo in
+dettaglio l'argomento dei permessi di file e directory in
+sez.~\ref{sec:file_access_control}). Se inoltre lo \itindex{sticky~bit}
+\textit{sticky bit} (vedi sez.~\ref{sec:file_special_perm}) è impostato
+occorrerà anche essere proprietari del file o proprietari della directory (o
+root, per cui nessuna delle restrizioni è applicata).
+
+Una delle caratteristiche di queste funzioni è che la creazione/rimozione del
+nome dalla directory e l'incremento/decremento del numero di riferimenti
+\itindex{inode} nell'\textit{inode} devono essere effettuati in maniera
+atomica (si veda sez.~\ref{sec:proc_atom_oper}) senza possibili interruzioni
+fra le due operazioni. Per questo entrambe queste funzioni sono realizzate
+tramite una singola system call.
+
+Si ricordi infine che un file non viene eliminato dal disco fintanto che tutti
+i riferimenti ad esso sono stati cancellati: solo quando il \textit{link
+ count} mantenuto \itindex{inode} nell'\textit{inode} diventa zero lo spazio
+occupato su disco viene rimosso (si ricordi comunque che a questo si aggiunge
+sempre un'ulteriore condizione,\footnote{come vedremo in
+ cap.~\ref{cha:file_unix_interface} il kernel mantiene anche una tabella dei
+ file aperti nei vari processi, che a sua volta contiene i riferimenti agli
+ \itindex{inode} \textit{inode} ad essi relativi. Prima di procedere alla
+ cancellazione dello spazio occupato su disco dal contenuto di un file il
+ kernel controlla anche questa tabella, per verificare che anche in essa non
+ ci sia più nessun riferimento all'\textit{inode} in questione.} e cioè che
+non ci siano processi che abbiano il suddetto file aperto).
+
+Questa proprietà viene spesso usata per essere sicuri di non lasciare file
+temporanei su disco in caso di crash dei programmi; la tecnica è quella di
+aprire il file e chiamare \func{unlink} subito dopo, in questo modo il
+contenuto del file è sempre disponibile all'interno del processo attraverso il
+suo file descriptor (vedi sez.~\ref{sec:file_fd}) fintanto che il processo non
+chiude il file, ma non ne resta traccia in nessuna directory, e lo spazio
+occupato su disco viene immediatamente rilasciato alla conclusione del
+processo (quando tutti i file vengono chiusi).
+
+
+\subsection{Le funzioni \func{remove} e \func{rename}}
+\label{sec:file_remove}
+
+Al contrario di quanto avviene con altri Unix, in Linux non è possibile usare
+\func{unlink} sulle directory; per cancellare una directory si può usare la
+funzione \func{rmdir} (vedi sez.~\ref{sec:file_dir_creat_rem}), oppure la
+funzione \funcd{remove}.
+
+Questa è la funzione prevista dallo standard ANSI C per cancellare un file o
+una directory (e funziona anche per i sistemi che non supportano i link
+diretti). Per i file è identica a \func{unlink} e per le directory è identica
+a \func{rmdir}; il suo prototipo è:
+\begin{prototype}{stdio.h}{int remove(const char *pathname)}
+ Cancella un nome dal filesystem.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso il file non viene toccato.
+
+ I codici di errore riportati in \var{errno} sono quelli della chiamata
+ utilizzata, pertanto si può fare riferimento a quanto illustrato nelle
+ descrizioni di \func{unlink} e \func{rmdir}.}
+\end{prototype}
+
+La funzione utilizza la funzione \func{unlink}\footnote{questo vale usando le
+ \acr{glibc}; nelle libc4 e nelle libc5 la funzione \func{remove} è un
+ semplice alias alla funzione \func{unlink} e quindi non può essere usata per
+ le directory.} per cancellare i file e la funzione \func{rmdir} per
+cancellare le directory; si tenga presente che per alcune implementazioni del
+protocollo NFS utilizzare questa funzione può comportare la scomparsa di file
+ancora in uso.
+
+Per cambiare nome ad un file o a una directory (che devono comunque essere
+nello stesso filesystem) si usa invece la funzione \funcd{rename},\footnote{la
+ funzione è definita dallo standard ANSI C, ma si applica solo per i file, lo
+ standard POSIX estende la funzione anche alle directory.} il cui prototipo
+è:
+\begin{prototype}{stdio.h}
+ {int rename(const char *oldpath, const char *newpath)}
+
+ Rinomina un file.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso il file non viene toccato. La variabile
+ \var{errno} viene impostata secondo i seguenti codici di errore:
+ \begin{errlist}
+ \item[\errcode{EISDIR}] \param{newpath} è una directory mentre
+ \param{oldpath} non è una directory.
+ \item[\errcode{EXDEV}] \param{oldpath} e \param{newpath} non sono sullo
+ stesso filesystem.
+ \item[\errcode{ENOTEMPTY}] \param{newpath} è una directory già esistente e
+ non vuota.
+ \item[\errcode{EBUSY}] o \param{oldpath} o \param{newpath} sono in uso da
+ parte di qualche processo (come directory di lavoro o come radice) o del
+ sistema (come mount point).
+ \item[\errcode{EINVAL}] \param{newpath} contiene un prefisso di
+ \param{oldpath} o più in generale si è cercato di creare una directory come
+ sotto-directory di se stessa.
+ \item[\errcode{ENOTDIR}] uno dei componenti dei \itindex{pathname}
+ \textit{pathname} non è una directory o \param{oldpath} è una directory e
+ \param{newpath} esiste e non è una directory.
+ \end{errlist}
+ ed inoltre \errval{EACCES}, \errval{EPERM}, \errval{EMLINK},
+ \errval{ENOENT}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP} e
+ \errval{ENOSPC}.}
+\end{prototype}
+
+La funzione rinomina il file \param{oldpath} in \param{newpath}, eseguendo se
+necessario lo spostamento di un file fra directory diverse. Eventuali altri
+link diretti allo stesso file non vengono influenzati.
+
+Il comportamento della funzione è diverso a seconda che si voglia rinominare
+un file o una directory; se ci riferisce ad un file allora \param{newpath}, se
+esiste, non deve essere una directory (altrimenti si ha l'errore
+\errcode{EISDIR}). Nel caso \param{newpath} indichi un file esistente questo
+viene cancellato e rimpiazzato (atomicamente).
+
+Se \param{oldpath} è una directory allora \param{newpath}, se esiste, deve
+essere una directory vuota, altrimenti si avranno gli errori \errcode{ENOTDIR}
+(se non è una directory) o \errcode{ENOTEMPTY} (se non è vuota). Chiaramente
+\param{newpath} non può contenere \param{oldpath} altrimenti si avrà un errore
+\errcode{EINVAL}.
+
+Se \param{oldpath} si riferisce ad un link simbolico questo sarà rinominato; se
+\param{newpath} è un link simbolico verrà cancellato come qualunque altro
+file. Infine qualora \param{oldpath} e \param{newpath} siano due nomi dello
+stesso file lo standard POSIX prevede che la funzione non dia errore, e non
+faccia nulla, lasciando entrambi i nomi; Linux segue questo standard, anche
+se, come fatto notare dal manuale delle \textit{glibc}, il comportamento più
+ragionevole sarebbe quello di cancellare \param{oldpath}.
+
+Il vantaggio nell'uso di questa funzione al posto della chiamata successiva di
+\func{link} e \func{unlink} è che l'operazione è eseguita atomicamente, non
+può esistere cioè nessun istante in cui un altro processo può trovare attivi
+entrambi i nomi dello stesso file, o, in caso di sostituzione di un file
+esistente, non trovare quest'ultimo prima che la sostituzione sia stata
+eseguita.
+
+In ogni caso se \param{newpath} esiste e l'operazione fallisce per un qualche
+motivo (come un crash del kernel), \func{rename} garantisce di lasciare
+presente un'istanza di \param{newpath}. Tuttavia nella sovrascrittura potrà
+esistere una finestra in cui sia \param{oldpath} che \param{newpath} fanno
+riferimento allo stesso file.
+
+
+\subsection{I link simbolici}
+\label{sec:file_symlink}
+
+Come abbiamo visto in sez.~\ref{sec:file_link} la funzione \func{link} crea
+riferimenti agli \itindex{inode} \textit{inode}, pertanto può funzionare
+soltanto per file che risiedono sullo stesso filesystem e solo per un
+filesystem di tipo Unix. Inoltre abbiamo visto che in Linux non è consentito
+eseguire un link diretto ad una directory.
+
+Per ovviare a queste limitazioni i sistemi Unix supportano un'altra forma di
+link (i cosiddetti \textit{soft link} o \textit{symbolic link}), che sono,
+come avviene in altri sistemi operativi, dei file speciali che contengono
+semplicemente il riferimento ad un altro file (o directory). In questo modo è
+possibile effettuare link anche attraverso filesystem diversi, a file posti in
+filesystem che non supportano i link diretti, a delle directory, ed anche a
+file che non esistono ancora.
+
+Il sistema funziona in quanto i link simbolici sono riconosciuti come tali dal
+kernel\footnote{è uno dei diversi tipi di file visti in
+ tab.~\ref{tab:file_file_types}, contrassegnato come tale
+ nell'\textit{inode}, e riconoscibile dal valore del campo \var{st\_mode}
+ della struttura \struct{stat} (vedi sez.~\ref{sec:file_stat}).} per cui
+alcune funzioni di libreria (come \func{open} o \func{stat}) quando ricevono
+come argomento un link simbolico vengono automaticamente applicate al file da
+esso specificato. La funzione che permette di creare un nuovo link simbolico
+è \funcd{symlink}, ed il suo prototipo è:
+\begin{prototype}{unistd.h}
+ {int symlink(const char *oldpath, const char *newpath)}
+ Crea un nuovo link simbolico di nome \param{newpath} il cui contenuto è
+ \param{oldpath}.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso la variabile \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EPERM}] il filesystem che contiene \param{newpath} non
+ supporta i link simbolici.
+ \item[\errcode{ENOENT}] una componente di \param{newpath} non esiste o
+ \param{oldpath} è una stringa vuota.
+ \item[\errcode{EEXIST}] esiste già un file \param{newpath}.
+ \item[\errcode{EROFS}] \param{newpath} è su un filesystem montato in sola
+ lettura.
+ \end{errlist}
+ ed inoltre \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG},
+ \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{ENOSPC} e
+ \errval{EIO}.}
+\end{prototype}
+
+Si tenga presente che la funzione non effettua nessun controllo sull'esistenza
+di un file di nome \param{oldpath}, ma si limita ad inserire quella stringa
+nel link simbolico. Pertanto un link simbolico può anche riferirsi ad un file
+che non esiste: in questo caso si ha quello che viene chiamato un
+\textit{dangling link}, letteralmente un \textsl{link ciondolante}.
+
+Come accennato i link simbolici sono risolti automaticamente dal kernel
+all'invocazione delle varie system call; in tab.~\ref{tab:file_symb_effect} si
+è riportato un elenco dei comportamenti delle varie funzioni di libreria che
+operano sui file nei confronti della risoluzione dei link simbolici,
+specificando quali seguono il link simbolico e quali invece possono operare
+direttamente sul suo contenuto.
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|c|}
+ \hline
+ \textbf{Funzione} & \textbf{Segue il link} & \textbf{Non segue il link} \\
+ \hline
+ \hline
+ \func{access} & $\bullet$ & -- \\
+ \func{chdir} & $\bullet$ & -- \\
+ \func{chmod} & $\bullet$ & -- \\
+ \func{chown} & -- & $\bullet$ \\
+ \func{creat} & $\bullet$ & -- \\
+ \func{exec} & $\bullet$ & -- \\
+ \func{lchown} & $\bullet$ & -- \\
+ \func{link}\footnotemark & -- & $\bullet$ \\
+ \func{lstat} & -- & $\bullet$ \\
+ \func{mkdir} & $\bullet$ & -- \\
+ \func{mkfifo} & $\bullet$ & -- \\
+ \func{mknod} & $\bullet$ & -- \\
+ \func{open} & $\bullet$ & -- \\
+ \func{opendir} & $\bullet$ & -- \\
+ \func{pathconf} & $\bullet$ & -- \\
+ \func{readlink} & -- & $\bullet$ \\
+ \func{remove} & -- & $\bullet$ \\
+ \func{rename} & -- & $\bullet$ \\
+ \func{stat} & $\bullet$ & -- \\
+ \func{truncate} & $\bullet$ & -- \\
+ \func{unlink} & -- & $\bullet$ \\
+ \hline
+ \end{tabular}
+ \caption{Uso dei link simbolici da parte di alcune funzioni.}
+ \label{tab:file_symb_effect}
+\end{table}
+
+\footnotetext{a partire dalla serie 2.0, e contrariamente a quanto indicato
+ dallo standard POSIX, si veda quanto detto in sez.~\ref{sec:file_link}.}
+
+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}, vedi sez.~\ref{sec:file_open}) e tutte le
+operazioni seguenti fanno riferimento solo a quest'ultimo.
+
+Dato che, come indicato in tab.~\ref{tab:file_symb_effect}, funzioni come la
+\func{open} seguono i link simbolici, occorrono funzioni apposite per accedere
+alle informazioni del link invece che a quelle del file a cui esso fa
+riferimento. Quando si vuole leggere il contenuto di un link simbolico si usa
+la funzione \funcd{readlink}, il cui prototipo è:
+\begin{prototype}{unistd.h}
+{int readlink(const char *path, char *buff, size\_t size)}
+ Legge il contenuto del link simbolico indicato da \param{path} nel buffer
+ \param{buff} di dimensione \param{size}.
+
+ \bodydesc{La funzione restituisce il numero di caratteri letti dentro
+ \param{buff} o -1 per un errore, nel qual caso la variabile
+ \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{path} non è un link simbolico o \param{size}
+ non è positiva.
+ \end{errlist}
+ ed inoltre \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{EACCES}, \errval{ELOOP}, \errval{EIO}, \errval{EFAULT} e
+ \errval{ENOMEM}.}
+\end{prototype}
+
+La funzione apre il link simbolico, ne legge il contenuto, lo scrive nel
+buffer, e lo richiude. Si tenga presente che la funzione non termina la
+stringa con un carattere nullo e la tronca alla dimensione specificata da
+\param{size} per evitare di sovrascrivere oltre le dimensioni del buffer.
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=8.5cm]{img/link_loop}
+ \caption{Esempio di loop nel filesystem creato con un link simbolico.}
+ \label{fig:file_link_loop}
+\end{figure}
+
+Un caso comune che si può avere con i link simbolici è la creazione dei
+cosiddetti \textit{loop}. La situazione è illustrata in
+fig.~\ref{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{il loop mostrato in
+ fig.~\ref{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 \textit{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
+lanciassimo un comando del tipo \code{grep -r linux *}, il loop nella
+directory porterebbe il comando ad esaminare \file{/boot}, \file{/boot/boot},
+\file{/boot/boot/boot} e così via.
+
+Per questo motivo il kernel e le librerie prevedono che nella risoluzione di
+un \itindex{pathname} \textit{pathname} possano essere seguiti un numero
+limitato di link simbolici, il cui valore limite è specificato dalla costante
+\const{MAXSYMLINKS}. Qualora questo limite venga superato viene generato un
+errore ed \var{errno} viene impostata al valore \errcode{ELOOP}.
+
+Un punto da tenere sempre presente è che, come abbiamo accennato, un link
+simbolico può fare riferimento anche ad un file che non esiste; ad esempio
+possiamo creare un file temporaneo nella nostra directory con un link del
+tipo:
+\begin{verbatim}
+$ ln -s /tmp/tmp_file temporaneo
+\end{verbatim}%$
+anche se \file{/tmp/tmp\_file} non esiste. Questo può generare confusione, in
+quanto aprendo in scrittura \file{temporaneo} verrà creato
+\file{/tmp/tmp\_file} e scritto; ma accedendo in sola lettura a
+\file{temporaneo}, ad esempio con \cmd{cat}, otterremmo:
+\begin{verbatim}
+$ cat temporaneo
+cat: temporaneo: No such file or directory
+\end{verbatim}%$
+con un errore che può sembrare sbagliato, dato che un'ispezione con \cmd{ls}
+ci mostrerebbe invece l'esistenza di \file{temporaneo}.
+
+
+\subsection{La creazione e la cancellazione delle directory}
+\label{sec:file_dir_creat_rem}
+
+Benché in sostanza le directory non siano altro che dei file contenenti
+elenchi di nomi ed \itindex{inode} \textit{inode}, non è possibile trattarle
+come file ordinari e devono essere create direttamente dal kernel attraverso
+una opportuna system call.\footnote{questo è quello che permette anche,
+ attraverso l'uso del VFS, l'utilizzo di diversi formati per la gestione dei
+ suddetti elenchi, dalle semplici liste a strutture complesse come alberi
+ binari, hash, ecc. che consentono una ricerca veloce quando il numero di
+ file è molto grande.} La funzione usata per creare una directory è
+\funcd{mkdir}, ed il suo prototipo è:
+\begin{functions}
+ \headdecl{sys/stat.h}
+ \headdecl{sys/types.h}
+ \funcdecl{int mkdir(const char *dirname, mode\_t mode)}
+
+ Crea una nuova directory.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EEXIST}] un file (o una directory) con quel nome esiste di
+ già.
+ \item[\errcode{EACCES}] non c'è il permesso di scrittura per la directory in
+ cui si vuole inserire la nuova directory.
+ \item[\errcode{EMLINK}] la directory in cui si vuole creare la nuova
+ directory contiene troppi file; sotto Linux questo normalmente non avviene
+ perché il filesystem standard consente la creazione di un numero di file
+ maggiore di quelli che possono essere contenuti nel disco, ma potendo
+ avere a che fare anche con filesystem di altri sistemi questo errore può
+ presentarsi.
+ \item[\errcode{ENOSPC}] non c'è abbastanza spazio sul file system per creare
+ la nuova directory o si è esaurita la quota disco dell'utente.
+ \end{errlist}
+ ed inoltre anche \errval{EPERM}, \errval{EFAULT}, \errval{ENAMETOOLONG},
+ \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
+ \errval{EROFS}.}
+\end{functions}
+
+La funzione crea una nuova directory vuota, che contiene cioè solo le due voci
+standard presenti in ogni directory (cioè ``\file{.}'' e ``\file{..}''), con
+il nome indicato dall'argomento \param{dirname}. Il nome può essere indicato
+sia come \itindex{pathname} \textit{pathname} assoluto che come
+\itindex{pathname} \textit{pathname} relativo.
+
+I permessi di accesso (vedi sez.~\ref{sec:file_access_control}) con cui la
+directory viene creata sono specificati dall'argomento \param{mode}, i cui
+possibili valori sono riportati in tab.~\ref{tab:file_permission_const}; si
+tenga presente che questi sono modificati dalla maschera di creazione dei file
+(si veda sez.~\ref{sec:file_perm_management}). La titolarità della nuova
+directory è impostata secondo quanto riportato in
+sez.~\ref{sec:file_ownership_management}.
+
+La funzione che permette la cancellazione di una directory è invece
+\funcd{rmdir}, ed il suo prototipo è:
+\begin{prototype}{sys/stat.h}{int rmdir(const char *dirname)}
+ Cancella una directory.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EPERM}] il filesystem non supporta la cancellazione di
+ directory, oppure la directory che contiene \param{dirname} ha lo
+ \itindex{sticky~bit} \textit{sticky bit} impostato e l'user-ID effettivo
+ del processo non corrisponde al proprietario della directory.
+ \item[\errcode{EACCES}] non c'è il permesso di scrittura per la directory
+ che contiene la directory che si vuole cancellare, o non c'è il permesso
+ di attraversare (esecuzione) una delle directory specificate in
+ \param{dirname}.
+ \item[\errcode{EBUSY}] la directory specificata è la directory di lavoro o la
+ radice di qualche processo.
+ \item[\errcode{ENOTEMPTY}] la directory non è vuota.
+ \end{errlist}
+ ed inoltre anche \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{EROFS}.}
+\end{prototype}
+
+La funzione cancella la directory \param{dirname}, che deve essere vuota (la
+directory deve cioè contenere soltanto le due voci standard ``\file{.}'' e
+``\file{..}''). Il nome può essere indicato con il \itindex{pathname}
+\textit{pathname} assoluto o relativo.
+
+La modalità con cui avviene la cancellazione è analoga a quella di
+\func{unlink}: fintanto che il numero di link \itindex{inode}
+all'\textit{inode} della directory non diventa nullo e nessun processo ha la
+directory aperta lo spazio occupato su disco non viene rilasciato. Se un
+processo ha la directory aperta la funzione rimuove il link \itindex{inode}
+all'\textit{inode} e nel caso sia l'ultimo, pure le voci standard ``\file{.}''
+e ``\file{..}'', a questo punto il kernel non consentirà di creare più nuovi
+file nella directory.
+
+
+\subsection{La creazione di file speciali}
+\label{sec:file_mknod}
+
+\index{file!di~dispositivo|(}
+
+Finora abbiamo parlato esclusivamente di file, directory e link simbolici; in
+sez.~\ref{sec:file_file_types} abbiamo visto però che il sistema prevede pure
+degli altri tipi di file speciali, come i file di dispositivo, le fifo ed i
+socket (questi ultimi sono un caso a parte, essendo associati anche alla
+comunicazione via rete, per cui ci saranno trattati in dettaglio a partire da
+cap.~\ref{cha:socket_intro}).
+
+La manipolazione delle caratteristiche di questi diversi tipi di file e la
+loro cancellazione può essere effettuata con le stesse funzioni che operano
+sui file regolari; ma quando li si devono creare sono necessarie delle
+funzioni apposite. La prima di queste funzioni è \funcd{mknod}, il cui
+prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h}
+ \headdecl{sys/stat.h}
+ \headdecl{fcntl.h}
+ \headdecl{unistd.h}
+ \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)}
+
+ Crea un \textit{inode} del tipo specificato sul filesystem.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EPERM}] non si hanno privilegi sufficienti a creare
+ l'\texttt{inode}, o il filesystem su cui si è cercato di
+ creare \param{pathname} non supporta l'operazione.
+ \item[\errcode{EINVAL}] il valore di \param{mode} non indica un file, una
+ fifo, un socket o un dispositivo.
+ \item[\errcode{EEXIST}] \param{pathname} esiste già o è un link simbolico.
+ \end{errlist}
+ ed inoltre anche \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG},
+ \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
+ \errval{ENOSPC}, \errval{EROFS}.}
+\end{functions}
+
+La funzione, come suggerisce il nome, permette di creare un ``\textsl{nodo}''
+sul filesystem, e viene in genere utilizzata per creare i file di dispositivo,
+ma si può usare anche per creare 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 binario. 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 link simbolici, si dovranno usare le funzioni \func{mkdir} e
+ \func{symlink} a questo dedicate.} un valore diverso comporterà l'errore
+\errcode{EINVAL}.
+
+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.
+
+I nuovi \itindex{inode} \textit{inode} creati con \func{mknod} apparterranno
+al proprietario e al gruppo del processo che li ha creati, a meno che non si
+sia attivato il bit \acr{sgid} per la directory o sia stata attivata la
+semantica BSD per il filesystem (si veda
+sez.~\ref{sec:file_ownership_management}) in cui si va a creare
+\itindex{inode} l'\textit{inode}.
+
+Nella creazione di un file di dispositivo occorre poi specificare
+correttamente il valore di \param{dev}; questo infatti è di tipo
+\type{dev\_t}, che è un tipo primitivo (vedi
+tab.~\ref{tab:intro_primitive_types}) riservato per indicare un
+\textsl{numero} di dispositivo; il kernel infatti identifica ciascun
+dispositivo con un valore numerico. Originariamente questo era un intero a 16
+bit diviso in due parti di 8 bit chiamate rispettivamente
+\itindex{major~number} \textit{major number} e \itindex{minor~number}
+\textit{minor number}, che sono poi i due numeri mostrati dal comando
+\texttt{ls -l} al posto della dimensione quando lo si esegue su un file di
+dispositivo.
+
+Il \itindex{major~number} \textit{major number} identifica una classe di
+dispositivi (ad esempio la seriale, o i dischi IDE) e serve in sostanza per
+indicare al kernel quale è il modulo che gestisce quella classe di
+dispositivi; per identificare uno specifico dispositivo di quella classe (ad
+esempio una singola porta seriale, o una partizione di un disco) si usa invece
+il \itindex{minor~number} \textit{minor number}. L'elenco aggiornato di questi
+numeri con le relative corrispondenze ai vari dispositivi può essere trovato
+nel file \texttt{Documentation/devices.txt} allegato alla documentazione dei
+sorgenti del kernel.
+
+Data la crescita nel numero di dispositivi supportati, ben presto il limite
+massimo di 256 si è rivelato troppo basso, e nel passaggio dai kernel della
+serie 2.4 alla serie 2.6 è stata aumentata a 32 bit la dimensione del tipo
+\type{dev\_t}, con delle dimensioni passate a 12 bit per il
+\itindex{major~number} \textit{major number} e 20 bit per il
+\itindex{minor~number} \textit{minor number}. La transizione però ha anche
+comportato il passaggio di \type{dev\_t} a \index{tipo!opaco} tipo opaco, e la
+necessità di specificare il numero tramite delle opportune macro, così da non
+avere problemi di compatibilità con eventuali ulteriori estensioni.
+
+Le macro sono definite nel file \file{sys/sysmacros.h}, che viene
+automaticamente incluso quando si include \file{sys/types.h}; si possono
+pertanto ottenere i valori del \itindex{major~number} \textit{major number} e
+\itindex{minor~number} \textit{minor number} di un dispositivo rispettivamente
+con le macro \macro{major} e \macro{minor}:
+\begin{functions}
+ \headdecl{sys/types.h}
+ \funcdecl{int \macro{major}(dev\_t dev)}
+ Restituisce il \itindex{major~number} \textit{major number} del dispositivo
+ \param{dev}.
+
+ \funcdecl{int \macro{minor}(dev\_t dev)}
+ Restituisce il \itindex{minor~number} \textit{minor number} del dispositivo
+ \param{dev}.
+\end{functions}
+\noindent mentre una volta che siano noti \itindex{major~number} \textit{major
+ number} e \itindex{minor~number} \textit{minor number} si potrà costruire il
+relativo identificativo con la macro \macro{makedev}:
+\begin{functions}
+ \headdecl{sys/types.h}
+ \funcdecl{dev\_t \macro{minor}(int major, int minor)}
+
+ Restituisce l'identificativo di un dispositivo dati \itindex{major~number}
+ \textit{major number} e \itindex{minor~number} \textit{minor number}.
+\end{functions}
+
+\index{file!di~dispositivo|)}
+
+Infine con lo standard POSIX.1-2001 è stata introdotta una funzione specifica
+per creare una fifo (tratteremo le fifo in in sez.~\ref{sec:ipc_named_pipe});
+la funzione è \funcd{mkfifo} ed il suo prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h} \headdecl{sys/stat.h}
+
+ \funcdecl{int mkfifo(const char *pathname, mode\_t mode)}
+
+ Crea una fifo.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso \var{errno} assumerà i valori \errval{EACCES},
+ \errval{EEXIST}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOSPC},
+ \errval{ENOTDIR} e \errval{EROFS}.}
+\end{functions}
+
+La funzione crea la fifo \param{pathname} con i permessi \param{mode}. Come
+per \func{mknod} il file \param{pathname} non deve esistere (neanche come link
+simbolico); al solito i permessi specificati da \param{mode} vengono
+modificati dal valore di \itindex{umask} \textit{umask}.
+
+
+
+\subsection{Accesso alle directory}
+\label{sec:file_dir_read}
+
+Benché le directory alla fine non siano altro che dei file che contengono
+delle liste di nomi ed \itindex{inode} \textit{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 sez.~\ref{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 tab.~\ref{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 erano
+ presenti in SVr4 e 4.3BSD, la loro specifica è riportata in POSIX.1-2001.}
+che ha introdotto una apposita interfaccia per la lettura delle directory,
+basata sui cosiddetti \textit{directory stream} (chiamati così per l'analogia
+con i file stream dell'interfaccia standard ANSI C di
+cap.~\ref{cha:files_std_interface}). La prima funzione di questa interfaccia è
+\funcd{opendir}, il cui prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h} \headdecl{dirent.h}
+
+ \funcdecl{DIR * opendir(const char *dirname)}
+
+ Apre un \textit{directory stream}.
+
+ \bodydesc{La funzione restituisce un puntatore al \textit{directory stream}
+ in caso di successo e \val{NULL} per un errore, nel qual caso \var{errno}
+ assumerà i valori \errval{EACCES}, \errval{EMFILE}, \errval{ENFILE},
+ \errval{ENOENT}, \errval{ENOMEM} e \errval{ENOTDIR}.}
+\end{functions}
+
+La funzione apre un \textit{directory stream} per la directory
+\param{dirname}, ritornando il puntatore ad un oggetto di tipo \type{DIR} (che
+è il \index{tipo!opaco} 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.
+
+Si tenga presente che comunque la funzione opera associando il
+\textit{directory stream} ad un opportuno file descriptor sottostante, sul
+quale vengono compiute le operazioni. Questo viene sempre aperto impostando il
+flag di \itindex{close-on-exec} \textit{close-on-exec}, così da evitare che
+resti aperto in caso di esecuzione di un altro programma.
+
+Nel caso in cui sia necessario conoscere il \textit{file descriptor} associato
+ad un \textit{directory stream} si può usare la funzione
+\funcd{dirfd},\footnote{questa funzione è una estensione introdotta con BSD
+ 4.3-Reno ed è presente in Linux con le libc5 (a partire dalla versione
+ 5.1.2) e con le \acr{glibc} ma non presente in POSIX fino alla revisione
+ POSIX.1-2008, per questo per poterla utilizzare fino alla versione 2.10
+ delle \acr{glibc} era necessario definire le macro \macro{\_BSD\_SOURCE} o
+ \macro{\_SVID\_SOURCE}, dalla versione 2.10 si possono usare anche
+ \texttt{\macro{\_POSIX\_C\_SOURCE} >= 200809L} o
+ \texttt{\macro{\_XOPEN\_SOURCE} >= 700}.} il cui prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h} \headdecl{dirent.h}
+
+ \funcdecl{int dirfd(DIR * dir)}
+
+ Restituisce il file descriptor associato ad un \textit{directory stream}.
+
+ \bodydesc{La funzione restituisce il file descriptor (un valore positivo) in
+ caso di successo e -1 in caso di errore.}
+\end{functions}
+
+La funzione restituisce il file descriptor associato al \textit{directory
+ stream} \param{dir}. Di solito si utilizza questa funzione in abbinamento a
+funzioni che operano sui file descriptor, ad esempio si potrà usare
+\func{fstat} per ottenere le proprietà della directory, o \func{fchdir} per
+spostare su di essa la directory di lavoro (vedi
+sez.~\ref{sec:file_work_dir}).
+
+Viceversa se si è aperto un file descriptor corrispondente ad una directory è
+possibile associarvi un \textit{directory stream} con la funzione
+\funcd{fdopendir},\footnote{questa funzione è però disponibile solo a partire
+ dalla versione 2.4 delle \acr{glibc}, ed è stata introdotta nello standard
+ POSIX solo a partire dalla revisione POSIX.1-2008, prima della versione 2.10
+ delle \acr{glibc} per poterla utilizzare era necessario definire la macro
+ \macro{\_GNU\_SOURCE}, dalla versione 2.10 si possono usare anche
+ \texttt{\macro{\_POSIX\_C\_SOURCE} >= 200809L} o \texttt{\_XOPEN\_SOURCE >=
+ 700} .} il cui prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h} \headdecl{dirent.h}
+
+ \funcdecl{DIR * fdopendir(int fd)}
+
+ Associa un \textit{directory stream} al file descriptor \param{fd}.
+
+ \bodydesc{La funzione restituisce un puntatore al \textit{directory stream}
+ in caso di successo e \val{NULL} per un errore, nel qual caso \var{errno}
+ assumerà il valore \errval{EBADF}.}
+\end{functions}
+
+La funzione è identica a \func{opendir}, ma ritorna un \textit{directory
+ stream} facendo riferimento ad un file descriptor \param{fd} che deve essere
+stato aperto in precedenza; la funzione darà un errore qualora questo non
+corrisponda ad una directory. L'uso di questa funzione permette di rispondere
+agli stessi requisiti delle funzioni ``\textit{at}'' che vedremo in
+sez.~\ref{sec:file_openat}.
+
+Una volta utilizzata il file descriptor verrà usato internamente dalle
+funzioni che operano sul \textit{directory stream} e non dovrà essere più
+utilizzato all'interno del proprio programma; in particolare dovrà essere
+chiuso con \func{closedir} e non direttamente. Si tenga presente inoltre che
+\func{fdopendir} non modifica lo stato di un eventuale flag di
+\itindex{close-on-exec} \textit{close-on-exec}, che pertanto dovrà essere
+impostato esplicitamente in fase di apertura del file descriptor.
+
+Una volta che si sia aperto un \textit{directory stream} la lettura del
+contenuto della directory viene effettuata attraverso la funzione
+\funcd{readdir}; il suo prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h} \headdecl{dirent.h}
+
+ \funcdecl{struct dirent *readdir(DIR *dir)}
+
+ Legge una voce dal \textit{directory stream}.
+
+ \bodydesc{La funzione restituisce il puntatore alla struttura contenente i
+ dati in caso di successo e \val{NULL} altrimenti, in caso di
+ \textit{directory stream} non valido \var{errno} assumerà il valore
+ \errval{EBADF}, il valore \val{NULL} viene restituito anche quando si
+ raggiunge la fine dello stream.}
+\end{functions}
+
+La funzione legge la voce corrente nella directory, posizionandosi sulla voce
+successiva. Pertanto se si vuole leggere l'intero contenuto di una directory
+occorrerà ripetere l'esecuzione della funzione fintanto che non si siano
+esaurite tutte le voci in essa presenti.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/dirent.c}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{dirent} per la lettura delle informazioni dei
+ file.}
+ \label{fig:file_dirent_struct}
+\end{figure}
+
+I dati vengono memorizzati in una struttura \struct{dirent}, la cui
+definizione è riportata in fig.~\ref{fig:file_dirent_struct}.\footnote{la
+ definizione è quella usata da Linux, che si trova nel file
+ \file{/usr/include/bits/dirent.h}, essa non contempla la presenza del campo
+ \var{d\_namlen} che indica la lunghezza del nome del file.} La funzione
+restituisce il puntatore alla struttura; si tenga presente però che
+quest'ultima è allocata staticamente, per cui viene sovrascritta tutte le
+volte che si ripete la lettura di una voce sullo stesso \textit{directory
+ stream}.
+
+Di questa funzione esiste anche una versione \index{funzioni!rientranti}
+rientrante, \func{readdir\_r},\footnote{per usarla è necessario definire una
+ qualunque delle macro \texttt{\macro{\_POSIX\_C\_SOURCE} >= 1},
+ \macro{\_XOPEN\_SOURCE}, \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE},
+ \macro{\_POSIX\_SOURCE}.} che non usa una struttura allocata staticamente, e
+può essere utilizzata anche con i \itindex{thread} \textit{thread}, il suo
+prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h} \headdecl{dirent.h}
+
+ \funcdecl{int readdir\_r(DIR *dir, struct dirent *entry,
+ struct dirent **result)}
+
+ Legge una voce dal \textit{directory stream}.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+ errore, gli errori sono gli stessi di \func{readdir}.}
+\end{functions}
+
+La funzione restituisce in \param{result} (come
+\itindex{value~result~argument} \textit{value result argument}) l'indirizzo
+dove sono stati salvati i dati, che di norma corrisponde a quello della
+struttura precedentemente allocata e specificata dall'argomento \param{entry},
+anche se non è assicurato che la funzione usi lo spazio fornito dall'utente.
+
+I vari campi di \struct{dirent} contengono le informazioni relative alle voci
+presenti nella directory; sia BSD che SVr4 prevedono che siano sempre presenti
+il campo \var{d\_name},\footnote{lo standard POSIX prevede invece solo la
+ presenza del campo \var{d\_fileno}, identico \var{d\_ino}, che in Linux è
+ definito come alias di quest'ultimo; il campo \var{d\_name} è considerato
+ dipendente dall'implementazione.} che contiene il nome del file nella forma
+di una stringa terminata da uno zero,\footnote{lo standard POSIX non specifica
+ una lunghezza, ma solo un limite \const{NAME\_MAX}; in SVr4 la lunghezza del
+ campo è definita come \code{NAME\_MAX+1} che di norma porta al valore di 256
+ byte usato anche in Linux.} ed il campo \var{d\_ino}, che contiene il numero
+di \textit{inode} cui il file è associato e corrisponde al campo \var{st\_ino}
+di \struct{stat}.
+
+La presenza di ulteriori campi opzionali oltre i due citati è segnalata dalla
+definizione di altrettante macro nella forma \code{\_DIRENT\_HAVE\_D\_XXX}
+dove \code{XXX} è il nome del relativo campo; nel caso di Linux sono pertanto
+definite le macro \macro{\_DIRENT\_HAVE\_D\_TYPE},
+\macro{\_DIRENT\_HAVE\_D\_OFF} e \macro{\_DIRENT\_HAVE\_D\_RECLEN}, mentre non
+è definita la macro \macro{\_DIRENT\_HAVE\_D\_NAMLEN}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Valore} & \textbf{Tipo di file} \\
+ \hline
+ \hline
+ \const{DT\_UNKNOWN} & Tipo sconosciuto.\\
+ \const{DT\_REG} & File normale.\\
+ \const{DT\_DIR} & Directory.\\
+ \const{DT\_LNK} & Link simbolico.\\
+ \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 (se fifo, directory, link simbolico, ecc.), e consente
+di evitare una successiva chiamata a \func{lstat} per determinarlo. I suoi
+possibili valori sono riportati in tab.~\ref{tab:file_dtype_macro}. Si tenga
+presente che questo valore è disponibile solo per i filesystem che ne
+supportano la restituzione (fra questi i più noti sono \textsl{btrfs},
+\textsl{ext2}, \textsl{ext3}, e \textsl{ext4}), per gli altri si otterrà
+sempre il valore \const{DT\_UNKNOWN}.\footnote{inoltre fino alla versione 2.1
+ delle \acr{glibc}, pur essendo il campo \var{d\_type} presente, il suo uso
+ non era implementato, e veniva restituito comunque il valore
+ \const{DT\_UNKNOWN}.}
+
+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
+\funcd{seekdir},\footnote{sia questa funzione che \func{telldir}, sono
+ estensioni prese da BSD, ed introdotte nello standard POSIX solo a partire
+ dalla revisione POSIX.1-2001, per poterle utilizzare deve essere definita
+ una delle macro \macro{\_XOPEN\_SOURCE}, \macro{\_BSD\_SOURCE} o
+ \macro{\_SVID\_SOURCE}.} 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 \funcd{telldir}, che
+legge la posizione corrente; il prototipo di quest'ultima è:\footnote{prima
+ delle \acr{glibc} 2.1.1 la funzione restituiva un valore di tipo
+ \type{off\_t}, sostituito a partire dalla versione 2.1.2 da \ctyp{long} per
+ conformità a POSIX.1-2001.}
+\begin{prototype}{dirent.h}{long 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 originariamente 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}, ed il file descriptor ad esso associato, 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 venne 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
+ \acr{libc4} e richiede siano definite le macro \macro{\_BSD\_SOURCE} o
+ \macro{\_SVID\_SOURCE}.} ed il suo prototipo è:
+\begin{prototype}{dirent.h}{int scandir(const char *dir,
+ struct dirent ***namelist, int(*filter)(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 (quella passata con
+l'argomento \param{filter}) e l'ordinamento di tutte le voci selezionate
+(quella specificata dell'argomento \param{compar}).
+
+La funzione legge tutte le voci della directory indicata dall'argomento
+\param{dir}, passando un puntatore a ciascuna di esse (una struttura
+\struct{dirent}) come argomento della funzione di selezione specificata da
+\param{filter}; se questa ritorna un valore diverso da zero il puntatore viene
+inserito in un vettore che viene allocato dinamicamente con \func{malloc}.
+Qualora si specifichi un valore \val{NULL} per l'argomento \func{filter} non
+viene fatta nessuna selezione e si ottengono tutte le voci presenti.
+
+Le voci selezionate possono essere riordinate tramite \func{qsort}, le modalità
+del riordinamento possono essere personalizzate usando la funzione
+\param{compar} come criterio di ordinamento di \func{qsort}, la funzione
+prende come argomenti le due strutture \struct{dirent} da confrontare
+restituendo un valore positivo, nullo o negativo per indicarne l'ordinamento;
+alla fine l'indirizzo della lista ordinata dei puntatori alle strutture
+\struct{dirent} viene restituito nell'argomento
+\param{namelist}.\footnote{la funzione alloca automaticamente la lista, e
+ restituisce, come \itindex{value~result~argument} \textit{value result
+ argument}, l'indirizzo della stessa; questo significa che \param{namelist}
+ deve essere dichiarato come \code{struct dirent **namelist} ed alla funzione
+ si deve passare il suo indirizzo.}
+
+Per l'ordinamento, vale a dire come valori possibili per l'argomento
+\param{compar} sono disponibili 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
+\acr{libc4}\footnote{la versione delle \acr{libc4} e \acr{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{compar} 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
+\texttt{file10} viene comunque dopo \texttt{file4}.)
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \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}
+
+Un semplice esempio dell'uso di queste funzioni è riportato in
+fig.~\ref{fig:file_my_ls}, dove si è riportata la sezione principale di un
+programma che, usando la funzione di scansione illustrata in
+fig.~\ref{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}).
+
+Il programma è estremamente semplice; in fig.~\ref{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 12--15}) di avere almeno un argomento (che indicherà la
+directory da esaminare) è chiamare (\texttt{\small 16}) la funzione
+\func{DirScan} per eseguire la scansione, usando la funzione \code{do\_ls}
+(\texttt{\small 22--29}) per fare tutto il lavoro.
+
+Quest'ultima si limita (\texttt{\small 26}) 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 27}) 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.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/DirScan.c}
+ \end{minipage}
+ \caption{Codice della funzione di scansione di una directory contenuta nel
+ file \file{DirScan.c}.}
+ \label{fig:file_dirscan}
+\end{figure}
+
+Tutto il grosso del lavoro è svolto dalla funzione \func{DirScan}, 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
+stream sulla directory passata come primo argomento, stampando un messaggio in
+caso di errore.
+
+Il passo successivo (\texttt{\small 23--24}) è cambiare 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 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 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}
+
+\itindbeg{pathname}
+
+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 \struct{task\_struct} (vedi fig.~\ref{fig:proc_task_struct}), più
+ precisamente nel campo \texttt{pwd} della sotto-struttura
+ \struct{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 corrente
+resta la stessa quando viene creato un processo figlio (vedi
+sez.~\ref{sec:proc_fork}), la directory corrente della shell diventa anche la
+directory corrente 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 di libreria,
+\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{prototype}{unistd.h}{char *getcwd(char *buffer, size\_t size)}
+ Legge il \textit{pathname} della directory di lavoro corrente.
+
+ \bodydesc{La funzione restituisce il puntatore \param{buffer} se riesce,
+ \val{NULL} se fallisce, in quest'ultimo caso la variabile
+ \var{errno} è impostata con i seguenti codici di errore:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] l'argomento \param{size} è zero e \param{buffer} non
+ è nullo.
+ \item[\errcode{ERANGE}] l'argomento \param{size} è più piccolo della
+ lunghezza del \textit{pathname}.
+ \item[\errcode{EACCES}] manca il permesso di lettura o di ricerca su uno dei
+ componenti del \textit{pathname} (cioè su una delle directory superiori
+ alla corrente).
+ \item[\errcode{ENOENT}] la directory di lavoro è stata eliminata.
+ \end{errlist}}
+\end{prototype}
+
+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 una
+volta cessato il suo utilizzo.
+
+Di questa funzione esiste una versione \code{char *getwd(char *buffer)} fatta
+per compatibilità all'indietro con BSD, che non consente di specificare la
+dimensione del buffer; esso deve essere allocato in precedenza ed avere una
+dimensione superiore a \const{PATH\_MAX} (di solito 256 byte, vedi
+sez.~\ref{sec:sys_limits}); il problema è che in Linux non esiste una
+dimensione superiore per 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.
+
+Un uso comune di \func{getcwd} è quello di salvare la directory di lavoro
+iniziale 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
+la directory corrente (vale a dire ``\texttt{.}'') e tornarvi in seguito con
+\func{fchdir}.
+
+Una seconda usata per ottenere la directory di lavoro è \code{char
+ *get\_current\_dir\_name(void)} che è sostanzialmente equivalente ad una
+\code{getcwd(NULL, 0)}, con la sola differenza che essa ritorna il valore
+della variabile di ambiente \val{PWD}, che essendo costruita dalla shell può
+contenere un \textit{pathname} comprendente anche dei link 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 link simbolici.
+
+Per cambiare la directory di lavoro si può usare la funzione \funcd{chdir}
+(equivalente del comando di shell \cmd{cd}) il cui nome sta appunto per
+\textit{change directory}, il suo prototipo è:
+\begin{prototype}{unistd.h}{int chdir(const char *pathname)}
+ Cambia la directory di lavoro in \param{pathname}.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e -1 per un errore,
+ nel qual caso \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{ENOTDIR}] non si è specificata una directory.
+ \item[\errcode{EACCES}] manca il permesso di ricerca su uno dei componenti
+ di \param{path}.
+ \end{errlist}
+ ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{ENOMEM}, \errval{ELOOP} e \errval{EIO}.}
+\end{prototype}
+\noindent ed ovviamente \param{pathname} deve indicare una directory per la
+quale si hanno i permessi di accesso.
+
+Dato che anche le directory sono file, è possibile riferirsi ad esse anche
+tramite il file descriptor, e non solo tramite il \textit{pathname}, per fare
+questo si usa \funcd{fchdir}, il cui prototipo è:
+\begin{prototype}{unistd.h}{int fchdir(int fd)}
+ Identica a \func{chdir}, ma usa il file descriptor \param{fd} invece del
+ \textit{pathname}.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, in caso di errore \var{errno} assumerà i valori \errval{EBADF} o
+ \errval{EACCES}.}
+\end{prototype}
+\noindent 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 accesso alla directory
+specificata da \param{fd}.
+
+\itindend{pathname}
+
+
+
+\subsection{I file temporanei}
+\label{sec:file_temp_file}
+
+In molte occasioni è utile poter creare dei file temporanei; benché la cosa
+sembri semplice, in realtà il problema è più sottile di quanto non appaia a
+prima vista. Infatti anche se sembrerebbe banale generare un nome a caso e
+creare il file dopo aver controllato che questo non esista, nel momento fra il
+controllo e la creazione si ha giusto lo spazio per una possibile
+\itindex{race~condition} \textit{race condition} (si ricordi quanto visto in
+sez.~\ref{sec:proc_race_cond}).
+
+Le \acr{glibc} provvedono varie funzioni per generare nomi di file temporanei,
+di cui si abbia certezza di unicità al momento della generazione; storicamente
+la prima di queste funzioni create a questo scopo era
+\funcd{tmpnam},\footnote{la funzione è stata deprecata nella revisione
+ POSIX.1-2008 dello standard POSIX.} il cui prototipo è:
+\begin{prototype}{stdio.h}{char *tmpnam(char *string)}
+ Genera un nome univoco per un file temporaneo.
+
+ \bodydesc{La funzione ritorna il puntatore alla stringa con il nome o
+ \val{NULL} in caso di fallimento. Non sono definiti errori.}
+\end{prototype}
+
+La funzione restituisce il puntatore ad una stringa contente un nome di file
+valido e non esistente al momento dell'invocazione; se si è passato come
+argomento \param{string} un puntatore non nullo ad un buffer di caratteri
+questo deve essere di dimensione \const{L\_tmpnam} ed il nome generato vi
+verrà copiato automaticamente; altrimenti il nome sarà generato in un buffer
+statico interno che verrà sovrascritto ad una chiamata successiva. Successive
+invocazioni della funzione continueranno a restituire nomi unici fino ad un
+massimo di \const{TMP\_MAX} volte, limite oltre il quale il comportamento è
+indefinito. Al nome viene automaticamente aggiunto come prefisso la directory
+specificata dalla costante \const{P\_tmpdir}.\footnote{le costanti
+ \const{L\_tmpnam}, \const{P\_tmpdir} e \const{TMP\_MAX} sono definite in
+ \file{stdio.h}.}
+
+Di questa funzione esiste una versione \index{funzioni!rientranti} rientrante,
+\func{tmpnam\_r}, che non fa nulla quando si passa \val{NULL} come argomento.
+Una funzione simile, \funcd{tempnam}, permette di specificare un prefisso per
+il file esplicitamente, il suo prototipo è:
+\begin{prototype}{stdio.h}{char *tempnam(const char *dir, const char *pfx)}
+ Genera un nome univoco per un file temporaneo.
+
+ \bodydesc{La funzione ritorna il puntatore alla stringa con il nome o
+ \val{NULL} in caso di fallimento, \var{errno} viene impostata a
+ \errval{ENOMEM} qualora fallisca l'allocazione della stringa.}
+\end{prototype}
+
+La funzione alloca con \code{malloc} la stringa in cui restituisce il nome,
+per cui è sempre \index{funzioni!rientranti} rientrante, occorre però
+ricordarsi di disallocare con \code{free} il puntatore che restituisce.
+L'argomento \param{pfx} specifica un prefisso di massimo 5 caratteri per il
+nome provvisorio. La funzione assegna come directory per il file temporaneo,
+verificando che esista e sia accessibile, la prima valida fra le seguenti:
+\begin{itemize*}
+\item La variabile di ambiente \const{TMPDIR} (non ha effetto se non è
+ definita o se il programma chiamante è \itindex{suid~bit} \acr{suid} o
+ \itindex{sgid~bit} \acr{sgid}, vedi sez.~\ref{sec:file_special_perm}).
+\item il valore dell'argomento \param{dir} (se diverso da \val{NULL}).
+\item Il valore della costante \const{P\_tmpdir}.
+\item la directory \file{/tmp}.
+\end{itemize*}
+
+In ogni caso, anche se la generazione del nome è casuale, ed è molto difficile
+ottenere un nome duplicato, nulla assicura che un altro processo non possa
+avere creato, fra l'ottenimento del nome e l'apertura del file, un altro file
+con lo stesso nome; per questo motivo quando si usa il nome ottenuto da una di
+queste funzioni occorre sempre aprire il nuovo file in modalità di esclusione
+(cioè con l'opzione \const{O\_EXCL} per i file descriptor o con il flag
+\code{x} per gli stream) che fa fallire l'apertura in caso il file sia già
+esistente.
+
+Per evitare di dovere effettuare a mano tutti questi controlli, lo standard
+POSIX definisce la funzione \funcd{tmpfile}, che permette di ottenere in
+maniera sicura l'accesso ad un file temporaneo, il suo prototipo è:
+\begin{prototype}{stdio.h}{FILE *tmpfile(void)}
+ Restituisce un file temporaneo aperto in lettura/scrittura.
+
+ \bodydesc{La funzione ritorna il puntatore allo stream associato al file
+ temporaneo in caso di successo e \val{NULL} in caso di errore, nel qual
+ caso \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+ \item[\errcode{EEXIST}] non è stato possibile generare un nome univoco.
+ \end{errlist}
+ ed inoltre \errval{EFAULT}, \errval{EMFILE}, \errval{ENFILE},
+ \errval{ENOSPC}, \errval{EROFS} e \errval{EACCES}.}
+\end{prototype}
+
+La funzione restituisce direttamente uno stream già aperto (in modalità
+\code{r+b}, si veda sez.~\ref{sec:file_fopen}) e pronto per l'uso, che viene
+automaticamente cancellato alla sua chiusura o all'uscita dal programma. Lo
+standard non specifica in quale directory verrà aperto il file, ma le
+\acr{glibc} prima tentano con \const{P\_tmpdir} e poi con \file{/tmp}. Questa
+funzione è \index{funzioni!rientranti} rientrante e non soffre di problemi di
+\itindex{race~condition} \textit{race condition}.
+
+Alcune versioni meno recenti di Unix non supportano queste funzioni; in questo
+caso si possono usare le vecchie funzioni \funcd{mktemp} e \func{mkstemp} che
+modificano una stringa di input che serve da modello e che deve essere
+conclusa da 6 caratteri \code{X} che verranno sostituiti da un codice
+unico. La prima delle due è analoga a \func{tmpnam} e genera un nome casuale,
+il suo prototipo è:
+\begin{prototype}{stlib.h}{char *mktemp(char *template)}
+ Genera un nome univoco per un file temporaneo.
+
+ \bodydesc{La funzione ritorna il puntatore \param{template} in caso di
+ successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
+ assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}.
+ \end{errlist}}
+\end{prototype}
+
+La funzionane genera un nome univoco sostituendo le \code{XXXXXX} finali di
+\param{template}; dato che \param{template} deve poter essere modificata dalla
+funzione non si può usare una stringa costante. Tutte le avvertenze riguardo
+alle possibili \itindex{race~condition} \textit{race condition} date per
+\func{tmpnam} continuano a valere; inoltre in alcune vecchie implementazioni
+il valore usato per sostituire le \code{XXXXXX} viene formato con il \acr{pid}
+del processo più una lettera, il che mette a disposizione solo 26 possibilità
+diverse per il nome del file, e rende il nome temporaneo facile da indovinare.
+Per tutti questi motivi la funzione è deprecata e non dovrebbe mai essere
+usata.
+
+La seconda funzione, \funcd{mkstemp} è sostanzialmente equivalente a
+\func{tmpfile}, ma restituisce un file descriptor invece di un nome; il suo
+prototipo è:
+\begin{prototype}{stlib.h}{int mkstemp(char *template)}
+ Genera un file temporaneo.
+
+ \bodydesc{La funzione ritorna il file descriptor in caso di successo e
+ -1 in caso di errore, nel qual caso \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}.
+ \item[\errcode{EEXIST}] non è riuscita a creare un file temporaneo, il
+ contenuto di \param{template} è indefinito.
+ \end{errlist}}
+\end{prototype}
+
+Come per \func{mktemp} anche in questo caso \param{template} non può essere
+una stringa costante. La funzione apre un file in lettura/scrittura con la
+funzione \func{open}, usando l'opzione \const{O\_EXCL} (si veda
+sez.~\ref{sec:file_open}), in questo modo al ritorno della funzione si ha la
+certezza di essere stati i creatori del file, i cui permessi (si veda
+sez.~\ref{sec:file_perm_overview}) sono impostati al valore \code{0600}
+(lettura e scrittura solo per il proprietario).\footnote{questo è vero a
+ partire dalle \acr{glibc} 2.0.7, le versioni precedenti delle \acr{glibc} e
+ le vecchie \acr{libc5} e \acr{libc4} usavano il valore \code{0666} che
+ permetteva a chiunque di leggere e scrivere i contenuti del file.} Di
+questa funzione esiste una variante \funcd{mkostemp}, introdotta
+specificamente dalla \acr{glibc},\footnote{la funzione è stata introdotta
+ nella versione 2.7 delle librerie e richiede che sia definita la macro
+ \const{\_GNU\_SOURCE}.} il cui prototipo è:
+\begin{prototype}{stlib.h}{int mkostemp(char *template, int flags)}
+ Genera un file temporaneo.
+
+ \bodydesc{La funzione ritorna il file descriptor in caso di successo e
+ -1 in caso di errore, con gli stessi errori di \func{mkstemp}.}
+\end{prototype}
+\noindent la cui sola differenza è la presenza dell'ulteriore argomento
+\var{flags} che consente di specificare i flag da passare ad \func{open}
+nell'apertura del file.
+
+
+In OpenBSD è stata introdotta un'altra funzione simile alle precedenti,
+\funcd{mkdtemp}, che crea invece una directory temporanea;\footnote{la
+ funzione è stata introdotta nelle \acr{glibc} a partire dalla versione
+ 2.1.91 ed inserita nello standard POSIX.1-2008.} il suo prototipo è:
+\begin{prototype}{stlib.h}{char *mkdtemp(char *template)}
+ Genera una directory temporanea.
+
+ \bodydesc{La funzione ritorna il puntatore al nome della directory in caso
+ successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
+ assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}.
+ \end{errlist}
+ più gli altri eventuali codici di errore di \func{mkdir}.}
+\end{prototype}
+
+La funzione genera una directory il cui nome è ottenuto sostituendo le
+\code{XXXXXX} finali di \param{template} con permessi \code{0700} (al solito
+si veda cap.~\ref{cha:file_unix_interface} per i dettagli); dato che la
+creazione della directory è sempre esclusiva i precedenti problemi di
+\itindex{race~condition} \textit{race condition} non si pongono.
+
+
+\section{La manipolazione delle caratteristiche dei file}
+\label{sec:file_infos}
+
+Come spiegato in sez.~\ref{sec:file_filesystem} tutte le informazioni generali
+relative alle caratteristiche di ciascun file, a partire dalle informazioni
+relative al controllo di accesso, sono mantenute \itindex{inode}
+nell'\textit{inode}.
+
+Vedremo in questa sezione come sia possibile leggere tutte queste informazioni
+usando la funzione \func{stat}, che permette l'accesso a tutti i dati
+memorizzati \itindex{inode} nell'\textit{inode}; esamineremo poi le varie
+funzioni usate per manipolare tutte queste informazioni (eccetto quelle che
+riguardano la gestione del controllo di accesso, trattate in in
+sez.~\ref{sec:file_access_control}).
+
+
+\subsection{La lettura delle caratteristiche dei file}
+\label{sec:file_stat}
+
+La lettura delle informazioni relative ai file è fatta attraverso la famiglia
+delle funzioni \func{stat} che sono quelle che usa il comando \cmd{ls} per
+poter ottenere e mostrare tutti i dati relativi ad un file; ne fanno parte le
+funzioni \funcd{stat}, \funcd{fstat} e \funcd{lstat}, i cui prototipi sono:
+\begin{functions}
+ \headdecl{sys/types.h}
+ \headdecl{sys/stat.h}
+ \headdecl{unistd.h}
+
+ \funcdecl{int stat(const char *file\_name, struct stat *buf)}
+ \funcdecl{int lstat(const char *file\_name, struct stat *buf)}
+ \funcdecl{int fstat(int filedes, struct stat *buf)}
+ Legge le informazioni di un file.
+
+ \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 per un
+ errore, nel qual caso \var{errno} assumerà uno dei valori: \errval{EBADF},
+ \errval{ENOENT}, \errval{ENOTDIR}, \errval{ELOOP}, \errval{EFAULT},
+ \errval{EACCES}, \errval{ENOMEM}, \errval{ENAMETOOLONG}.}
+\end{functions}
+
+La funzione \func{stat} legge le informazioni del file il cui pathname è
+specificato dalla stringa puntata da \param{file\_name} e le inserisce nel
+buffer puntato dall'argomento \param{buf}; la funzione \func{lstat} è identica
+a \func{stat} eccetto che se \param{file\_name} è un link simbolico vengono
+lette le informazioni relative ad esso e non al file a cui fa
+riferimento. Infine \func{fstat} esegue la stessa operazione su un file già
+aperto, specificato tramite il suo file descriptor \param{filedes}.
+
+La struttura \struct{stat} usata da queste funzioni è definita nell'header
+\file{sys/stat.h} e in generale dipende dall'implementazione; la versione
+usata da Linux è mostrata in fig.~\ref{fig:file_stat_struct}, così come
+riportata dalla pagina di manuale di \func{stat}; in realtà la definizione
+effettivamente usata nel kernel dipende dall'architettura e ha altri campi
+riservati per estensioni come tempi dei file più precisi (vedi
+sez.~\ref{sec:file_file_times}), o per il padding dei campi.
+
+\begin{figure}[!htb]
+ \footnotesize
+ \centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/stat.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{stat} per la lettura delle informazioni dei
+ file.}
+ \label{fig:file_stat_struct}
+\end{figure}
+
+Si noti come i vari membri della struttura siano specificati come tipi
+primitivi del sistema (di quelli definiti in
+tab.~\ref{tab:intro_primitive_types}, e dichiarati in \file{sys/types.h}).
+
+\subsection{I tipi di file}
+\label{sec:file_types}
+
+Come riportato in tab.~\ref{tab:file_file_types} in Linux oltre ai file e alle
+directory esistono altri oggetti che possono stare su un filesystem. Il tipo
+di file è ritornato dalla funzione \func{stat} come maschera binaria nel campo
+\var{st\_mode} (che contiene anche le informazioni relative ai permessi) di
+una struttura \struct{stat}.
+
+Dato che il valore numerico può variare a seconda delle implementazioni, lo
+standard POSIX definisce un insieme di macro per verificare il tipo di file,
+queste vengono usate anche da Linux che supporta pure le estensioni allo
+standard per i link simbolici e i socket definite da BSD; l'elenco completo
+delle macro con cui è possibile estrarre l'informazione da \var{st\_mode} è
+riportato in tab.~\ref{tab:file_type_macro}.
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Macro} & \textbf{Tipo del file} \\
+ \hline
+ \hline
+ \macro{S\_ISREG(m)} & file normale.\\
+ \macro{S\_ISDIR(m)} & directory.\\
+ \macro{S\_ISCHR(m)} & dispositivo a caratteri.\\
+ \macro{S\_ISBLK(m)} & dispositivo a blocchi.\\
+ \macro{S\_ISFIFO(m)} & fifo.\\
+ \macro{S\_ISLNK(m)} & link simbolico.\\
+ \macro{S\_ISSOCK(m)} & socket.\\
+ \hline
+ \end{tabular}
+ \caption{Macro per i tipi di file (definite in \texttt{sys/stat.h}).}
+ \label{tab:file_type_macro}
+\end{table}
+
+Oltre alle macro di tab.~\ref{tab:file_type_macro} è possibile usare
+direttamente il valore di \var{st\_mode} per ricavare il tipo di file
+controllando direttamente i vari bit in esso memorizzati. Per questo sempre in
+\file{sys/stat.h} sono definite le costanti numeriche riportate in
+tab.~\ref{tab:file_mode_flags}.
+
+Il primo valore dell'elenco di tab.~\ref{tab:file_mode_flags} è la maschera
+binaria che permette di estrarre i bit nei quali viene memorizzato il tipo di
+file, i valori successivi sono le costanti corrispondenti ai singoli bit, e
+possono essere usati per effettuare la selezione sul tipo di file voluto, con
+un'opportuna combinazione.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|l|}
+ \hline
+ \textbf{Flag} & \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{S\_IFMT} & 0170000 & Maschera per i bit del tipo di file.\\
+ \const{S\_IFSOCK} & 0140000 & Socket.\\
+ \const{S\_IFLNK} & 0120000 & Link simbolico.\\
+ \const{S\_IFREG} & 0100000 & File regolare.\\
+ \const{S\_IFBLK} & 0060000 & Dispositivo a blocchi.\\
+ \const{S\_IFDIR} & 0040000 & Directory.\\
+ \const{S\_IFCHR} & 0020000 & Dispositivo a caratteri.\\
+ \const{S\_IFIFO} & 0010000 & Fifo.\\
+ \hline
+ \const{S\_ISUID} & 0004000 & Set UID bit \itindex{suid~bit}.\\
+ \const{S\_ISGID} & 0002000 & Set GID bit \itindex{sgid~bit}.\\
+ \const{S\_ISVTX} & 0001000 & Sticky bit \itindex{sticky~bit}.\\
+ \hline
+% \const{S\_IRWXU} & 00700 & Bitmask per i permessi del proprietario.\\
+ \const{S\_IRUSR} & 00400 & Il proprietario ha permesso di lettura.\\
+ \const{S\_IWUSR} & 00200 & Il proprietario ha permesso di scrittura.\\
+ \const{S\_IXUSR} & 00100 & Il proprietario ha permesso di esecuzione.\\
+ \hline
+% \const{S\_IRWXG} & 00070 & Bitmask per i permessi del gruppo.\\
+ \const{S\_IRGRP} & 00040 & Il gruppo ha permesso di lettura.\\
+ \const{S\_IWGRP} & 00020 & Il gruppo ha permesso di scrittura.\\
+ \const{S\_IXGRP} & 00010 & Il gruppo ha permesso di esecuzione.\\
+ \hline
+% \const{S\_IRWXO} & 00007 & Bitmask per i permessi di tutti gli altri\\
+ \const{S\_IROTH} & 00004 & Gli altri hanno permesso di lettura.\\
+ \const{S\_IWOTH} & 00002 & Gli altri hanno permesso di esecuzione.\\
+ \const{S\_IXOTH} & 00001 & Gli altri hanno permesso di esecuzione.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti per l'identificazione dei vari bit che compongono il campo
+ \var{st\_mode} (definite in \file{sys/stat.h}).}
+ \label{tab:file_mode_flags}
+\end{table}
+
+Ad esempio se si volesse impostare una condizione che permetta di controllare
+se un file è una directory o un file ordinario si potrebbe definire la macro
+di preprocessore:
+\includecodesnip{listati/is_file_dir.h}
+in cui prima si estraggono da \var{st\_mode} i bit relativi al tipo di file e
+poi si effettua il confronto con la combinazione di tipi scelta.
+
+
+\subsection{Le dimensioni dei file}
+\label{sec:file_file_size}
+
+Il campo \var{st\_size} di una struttura \struct{stat} contiene la dimensione
+del file in byte, se si tratta di un file regolare. Nel caso di un link
+simbolico la dimensione è quella del \itindex{pathname} \textit{pathname} che
+il link stesso contiene; per le fifo questo campo è sempre nullo.
+
+Il campo \var{st\_blocks} definisce la lunghezza del file in blocchi di 512
+byte. Il campo \var{st\_blksize} infine definisce la dimensione preferita per
+i trasferimenti sui file (che è la dimensione usata anche dalle librerie del C
+per l'interfaccia degli stream); scrivere sul file a blocchi di dati di
+dimensione inferiore sarebbe inefficiente.
+
+Si tenga conto che la lunghezza del file riportata in \var{st\_size} non è
+detto che corrisponda all'occupazione dello spazio su disco per via della
+possibile esistenza dei cosiddetti \index{file!\textit{hole}} \textit{holes}
+(letteralmente \textsl{buchi}) che si formano tutte le volte che si va a
+scrivere su un \itindex{sparse~file} file dopo aver eseguito uno spostamento
+oltre la sua fine (tratteremo in dettaglio l'argomento in
+sez.~\ref{sec:file_lseek}).
+
+In questo caso si avranno risultati differenti a seconda del modo in cui si
+calcola la lunghezza del file, ad esempio il comando \cmd{du}, (che riporta il
+numero di blocchi occupati) potrà dare una dimensione inferiore, mentre se si
+legge dal file (ad esempio usando il comando \cmd{wc -c}), dato che in tal
+caso per le parti non scritte vengono restituiti degli zeri, si avrà lo stesso
+risultato di \cmd{ls}.
+
+Se è sempre possibile allargare un file, scrivendoci sopra od usando la
+funzione \func{lseek} per spostarsi oltre la sua fine, esistono anche casi in
+cui si può avere bisogno di effettuare un troncamento, scartando i dati
+presenti al di là della dimensione scelta come nuova fine del file.
+
+Un file può sempre essere troncato a zero aprendolo con il flag
+\const{O\_TRUNC}, ma questo è un caso particolare; per qualunque altra
+dimensione si possono usare le due funzioni \funcd{truncate} e
+\funcd{ftruncate}, i cui prototipi sono:
+\begin{functions}
+ \headdecl{unistd.h}
+
+ \funcdecl{int truncate(const char *file\_name, off\_t length)}
+
+ \funcdecl{int ftruncate(int fd, off\_t length))}
+
+ Troncano un file alla lunghezza \param{length}.
+
+ \bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per un
+ errore, nel qual caso \var{errno} viene impostata opportunamente; per
+ \func{ftruncate} si hanno i valori:
+ \begin{errlist}
+ \item[\errcode{EBADF}] \param{fd} non è un file descriptor.
+ \item[\errcode{EINVAL}] \param{fd} è un riferimento ad un socket, non a un
+ file o non è aperto in scrittura.
+ \end{errlist}
+ per \func{truncate} si hanno:
+ \begin{errlist}
+ \item[\errcode{EACCES}] il file non ha permesso di scrittura o non si ha il
+ permesso di esecuzione una delle directory del \itindex{pathname}
+ \textit{pathname}.
+ \item[\errcode{ETXTBSY}] il file è un programma in esecuzione.
+ \end{errlist}
+ ed anche \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{EROFS}, \errval{EIO}, \errval{EFAULT}, \errval{ELOOP}.}
+\end{functions}
+
+Entrambe le funzioni fan sì che la dimensione del file sia troncata ad un
+valore massimo specificato da \param{length}, e si distinguono solo per il
+fatto che il file viene indicato con il pathname \param{file\_name} per
+\func{truncate} e con il file descriptor \param{fd} per \funcd{ftruncate}; se
+il file è più lungo della lunghezza specificata i dati in eccesso saranno
+perduti.
+
+Il comportamento in caso di lunghezza inferiore non è specificato e dipende
+dall'implementazione: il file può essere lasciato invariato o esteso fino alla
+lunghezza scelta; nel caso di Linux viene esteso con la creazione di un
+\index{file!\textit{hole}} \textsl{buco} nel \itindex{sparse~file} file e ad
+una lettura si otterranno degli zeri; si tenga presente però che questo
+comportamento è supportato solo per filesystem nativi, ad esempio su un
+filesystem non nativo come il VFAT di Windows questo non è possibile.
+
+\subsection{I tempi dei file}
+\label{sec:file_file_times}
+
+Il sistema mantiene per ciascun file tre tempi, questi sono registrati
+\itindex{inode} nell'\textit{inode} insieme agli altri attributi del file e
+possono essere letti tramite la funzione \func{stat}, che li restituisce
+attraverso tre specifici campi della struttura \struct{stat} di
+fig.~\ref{fig:file_stat_struct}. Il significato di detti tempi e dei relativi
+campi è riportato nello schema in tab.~\ref{tab:file_file_times}, dove è anche
+riportato un esempio delle funzioni che effettuano cambiamenti su di essi. Il
+valore è espresso nel cosiddetto \itindex{calendar~time} \textit{calendar
+ time}, su cui torneremo in dettaglio in sez.~\ref{sec:sys_time}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|c|l|l|c|}
+ \hline
+ \textbf{Membro} & \textbf{Significato} & \textbf{Funzione}
+ & \textbf{Opzione di \cmd{ls}} \\
+ \hline
+ \hline
+ \var{st\_atime}& ultimo accesso ai dati del file &
+ \func{read}, \func{utime} & \cmd{-u}\\
+ \var{st\_mtime}& ultima modifica ai dati del file &
+ \func{write}, \func{utime} & default\\
+ \var{st\_ctime}& ultima modifica ai dati dell'\textit{inode} &
+ \func{chmod}, \func{utime} & \cmd{-c}\\
+ \hline
+ \end{tabular}
+ \caption{I tre tempi associati a ciascun file.}
+ \label{tab:file_file_times}
+\end{table}
+
+Il primo punto da tenere presente è la differenza fra il cosiddetto tempo di
+ultima modifica (il \textit{modification time}, \var{st\_mtime}) e il tempo di
+ultimo cambiamento di stato (il \textit{change time}, \var{st\_ctime}). Il
+primo infatti fa riferimento ad una modifica del contenuto di un file, mentre
+il secondo ad una modifica \itindex{inode} dell'\textit{inode}. Dato che
+esistono molte operazioni, come la funzione \func{link} e altre che vedremo in
+seguito, che modificano solo le informazioni contenute \itindex{inode}
+nell'\textit{inode} senza toccare il contenuto del file, diventa necessario
+l'utilizzo di questo secondo tempo.
+
+Il tempo di ultima modifica viene usato ad esempio da programmi come
+\cmd{make} per decidere quali file necessitano di essere ricompilati o
+(talvolta insieme anche al tempo di cambiamento di stato) per decidere quali
+file devono essere archiviati per il backup. Il tempo di ultimo accesso viene
+di solito usato per identificare i file che non vengono più utilizzati per un
+certo lasso di tempo. Ad esempio un programma come \texttt{leafnode} lo usa
+per cancellare gli articoli letti più vecchi, mentre \texttt{mutt} lo usa per
+marcare i messaggi di posta che risultano letti. Il sistema non tiene conto
+dell'ultimo accesso \itindex{inode} all'\textit{inode}, pertanto funzioni come
+\func{access} o \func{stat} non hanno alcuna influenza sui tre tempi. Il
+comando \cmd{ls} (quando usato con le opzioni \cmd{-l} o \cmd{-t}) mostra i
+tempi dei file secondo lo schema riportato nell'ultima colonna di
+tab.~\ref{tab:file_file_times}.
+
+L'aggiornamento del tempo di ultimo accesso è stato a lungo considerato un
+difetto progettuale di Unix, questo infatti comporta la necessità di
+effettuare un accesso in scrittura sul disco anche in tutti i casi in cui
+questa informazione non interessa e sarebbe possibile avere un semplice
+accesso in lettura sui dati bufferizzati. Questo comporta un ovvio costo sia
+in termini di prestazioni, che di consumo di risorse come la batteria per i
+portatili, o cicli di riscrittura per i dischi su memorie riscrivibili.
+
+Per questo motivo, onde evitare di mantenere una informazione che nella
+maggior parte dei casi non interessa, è sempre stato possibile disabilitare
+l'aggiornamento del tempo di ultimo accesso con l'opzione di montaggio
+\texttt{noatime}. Dato però che questo può creare problemi a qualche
+programma, in Linux è stata introdotta la opzione \texttt{relatime} che esegue
+l'aggiornamento soltanto se il tempo di ultimo accesso è precedente al tempo di
+ultima modifica o cambiamento, così da rendere evidente che vi è stato un
+accesso dopo la scrittura, ed evitando al contempo ulteriori operazioni su
+disco negli accessi successivi. In questo modo l'informazione relativa al
+fatto che un file sia stato letto resta disponibile, e ad esempio i programmi
+citati in precedenza continuano a funzionare. Questa opzione, a partire dal
+kernel 2.6.30, è diventata il comportamento di default e non deve più essere
+specificata esplicitamente.\footnote{si può comunque riottenere il vecchio
+ comportamento usando la opzione di montaggio \texttt{strictatime}.}
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|c|c|c|c|c|l|}
+ \hline
+ \multicolumn{1}{|p{3cm}|}{\centering{\vspace{6pt}\textbf{Funzione}}} &
+ \multicolumn{3}{|p{3.6cm}|}{\centering{
+ \textbf{File o directory del riferimento}}}&
+ \multicolumn{3}{|p{3.6cm}|}{\centering{
+ \textbf{Directory contenente il riferimento}}}
+ &\multicolumn{1}{|p{3.6cm}|}{\centering{\vspace{6pt}\textbf{Note}}} \\
+ \cline{2-7}
+ \cline{2-7}
+ \multicolumn{1}{|p{3cm}|}{}
+ &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(a)}}}
+ &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(m)}}}
+ &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(c)}}}
+ &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(a)}}}
+ &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(m)}}}
+ &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(c)}}}
+ &\multicolumn{1}{|p{3cm}|}{} \\
+ \hline
+ \hline
+ \func{chmod}, \func{fchmod}
+ & -- & -- &$\bullet$& -- & -- & -- &\\
+ \func{chown}, \func{fchown}
+ & -- & -- &$\bullet$& -- & -- & -- &\\
+ \func{creat}
+ &$\bullet$&$\bullet$&$\bullet$& -- &$\bullet$&$\bullet$&
+ con \const{O\_CREATE} \\
+ \func{creat}
+ & -- &$\bullet$&$\bullet$& -- &$\bullet$&$\bullet$&
+ con \const{O\_TRUNC} \\
+ \func{exec}
+ &$\bullet$& -- & -- & -- & -- & -- &\\
+ \func{lchown}
+ & -- & -- &$\bullet$& -- & -- & -- &\\
+ \func{link}
+ & -- & -- &$\bullet$& -- &$\bullet$&$\bullet$&\\
+ \func{mkdir}
+ &$\bullet$&$\bullet$&$\bullet$& -- &$\bullet$&$\bullet$&\\
+ \func{mkfifo}
+ &$\bullet$&$\bullet$&$\bullet$& -- &$\bullet$&$\bullet$&\\
+ \func{open}
+ &$\bullet$&$\bullet$&$\bullet$& -- &$\bullet$&$\bullet$&
+ con \const{O\_CREATE} \\
+ \func{open}
+ & -- &$\bullet$&$\bullet$& -- & -- & -- &
+ con \const{O\_TRUNC} \\
+ \func{pipe}
+ &$\bullet$&$\bullet$&$\bullet$& -- & -- & -- &\\
+ \func{read}
+ &$\bullet$& -- & -- & -- & -- & -- &\\
+ \func{remove}
+ & -- & -- &$\bullet$& -- &$\bullet$&$\bullet$&
+ se esegue \func{unlink}\\
+ \func{remove}
+ & -- & -- & -- & -- &$\bullet$&$\bullet$&
+ se esegue \func{rmdir}\\
+ \func{rename}
+ & -- & -- &$\bullet$& -- &$\bullet$&$\bullet$&
+ per entrambi gli argomenti\\
+ \func{rmdir}
+ & -- & -- & -- & -- &$\bullet$&$\bullet$&\\
+ \func{truncate}, \func{ftruncate}
+ & -- &$\bullet$&$\bullet$& -- & -- & -- &\\
+ \func{unlink}
+ & -- & -- &$\bullet$& -- &$\bullet$&$\bullet$&\\
+ \func{utime}
+ &$\bullet$&$\bullet$&$\bullet$& -- & -- & -- &\\
+ \func{write}
+ & -- &$\bullet$&$\bullet$& -- & -- & -- &\\
+ \hline
+ \end{tabular}
+ \caption{Prospetto dei cambiamenti effettuati sui tempi di ultimo
+ accesso \textsl{(a)}, ultima modifica \textsl{(m)} e ultimo cambiamento
+ \textsl{(c)} dalle varie funzioni operanti su file e directory.}
+ \label{tab:file_times_effects}
+\end{table}
+
+
+L'effetto delle varie funzioni di manipolazione dei file sui relativi tempi è
+illustrato in tab.~\ref{tab:file_times_effects}, facendo riferimento al
+comportamento classico per quanto riguarda \var{st\_atime}. Si sono riportati
+gli effetti sia per il file a cui si fa riferimento, sia per la directory che
+lo contiene; questi ultimi possono essere capiti se si tiene conto di quanto
+già detto, e cioè che anche le directory sono anch'esse file che contengono
+una lista di nomi, che il sistema tratta in maniera del tutto analoga a tutti
+gli altri.
+
+Per questo motivo tutte le volte che compiremo un'operazione su un file che
+comporta una modifica del nome contenuto nella directory, andremo anche a
+scrivere sulla directory che lo contiene cambiandone il tempo di modifica. Un
+esempio di questo tipo di operazione può essere la cancellazione di un file,
+invece leggere o scrivere o cambiare i permessi di un file ha effetti solo sui
+tempi di quest'ultimo.
+
+Si noti infine come \var{st\_ctime} non abbia nulla a che fare con il tempo di
+creazione del file, usato in molti altri sistemi operativi, ma che in Unix non
+esiste. Per questo motivo quando si copia un file, a meno di preservare
+esplicitamente i tempi (ad esempio con l'opzione \cmd{-p} di \cmd{cp}) esso
+avrà sempre il tempo corrente come data di ultima modifica.
+
+I tempi di ultimo accesso e modifica possono essere modificati esplicitamente
+usando la funzione \funcd{utime}, il cui prototipo è:
+\begin{prototype}{utime.h}
+ {int utime(const char *filename, struct utimbuf *times)}
+ Modifica i tempi di ultimo accesso e modifica di un file.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+ errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] non si ha il permesso di scrittura sul file.
+ \item[\errcode{EPERM}] non si è proprietari del file.
+ \end{errlist}
+ ed inoltre \errval{EROFS} e \errval{ENOENT}.}
+\end{prototype}
+
+La funzione cambia i tempi di ultimo accesso e modifica del file specificato
+dall'argomento \param{filename}, e richiede come secondo argomento il
+puntatore ad una struttura \struct{utimbuf}, la cui definizione è riportata in
+fig.~\ref{fig:struct_utimebuf}, con i nuovi valori di detti tempi
+(rispettivamente nei campi \var{actime} e \var{modtime}). Se si passa un
+puntatore nullo verrà impostato il tempo corrente.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/utimbuf.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{utimbuf}, usata da \func{utime} per modificare
+ i tempi dei file.}
+ \label{fig:struct_utimebuf}
+\end{figure}
+
+L'effetto della funzione e i privilegi necessari per eseguirla dipendono da
+cosa è l'argomento \param{times}; se è \val{NULL} la funzione imposta il
+tempo corrente ed è sufficiente avere accesso in scrittura al file; se invece
+si è specificato un valore la funzione avrà successo solo se si è proprietari
+del file o si hanno i privilegi di amministratore.
+
+Si tenga presente che non è comunque possibile specificare il tempo di
+cambiamento di stato del file, che viene aggiornato direttamente dal kernel
+tutte le volte che si modifica \itindex{inode} l'\textit{inode} (quindi anche
+alla chiamata di \func{utime}). Questo serve anche come misura di sicurezza
+per evitare che si possa modificare un file nascondendo completamente le
+proprie tracce. In realtà la cosa resta possibile se si è in grado di accedere
+al \index{file!di~dispositivo} file di dispositivo, scrivendo direttamente sul
+disco senza passare attraverso il filesystem, ma ovviamente in questo modo la
+cosa è più complicata da realizzare.
+
+A partire dal kernel 2.6 la risoluzione dei tempi dei file, che nei campi di
+tab.~\ref{tab:file_file_times} è espressa in secondi, è stata portata ai
+nanosecondi per la gran parte dei filesystem. La ulteriore informazione può
+essere acceduta attraverso altri campi appositamente aggiunti alla struttura
+\struct{stat}. Se si sono definite le macro \macro{\_BSD\_SOURCE} o
+\macro{\_SVID\_SOURCE} questi sono \var{st\_atim.tv\_nsec},
+\var{st\_mtim.tv\_nsec} e \var{st\_ctim.tv\_nsec} se queste non sono definite,
+\var{st\_atimensec}, \var{st\_mtimensec} e \var{st\_mtimensec}. Qualora il
+supporto per questa maggior precisione sia assente questi campi aggiuntivi
+saranno nulli.
+
+Per la gestione di questi nuovi valori è stata definita una seconda funzione
+di modifica, \funcd{utimes}, che consente di specificare tempi con maggior
+precisione; il suo prototipo è:
+\begin{prototype}
+ {sys/time.h}
+ {int utimes(const char *filename, struct timeval times[2])}
+ Modifica i tempi di ultimo accesso e modifica di un file.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+ errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] non si ha il permesso di scrittura sul file.
+ \item[\errcode{EPERM}] non si è proprietari del file.
+ \end{errlist}
+ ed inoltre \errval{EROFS} e \errval{ENOENT}.}
+\end{prototype}
+
+La funzione è del tutto analoga alla precedente \func{utime} ma usa come
+secondo argomento un vettore di due strutture \struct{timeval}, la cui
+definizione è riportata in fig.~\ref{fig:sys_timeval_struct}, che consentono
+di indicare i tempi con una precisione del microsecondo. Il primo elemento
+di \param{times} indica il valore per il tempo di ultimo accesso, il secondo
+quello per il tempo di ultima modifica. Se si indica come secondo argomento un
+puntatore nullo di nuovo verrà utilizzato il tempo corrente.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/timeval.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{timeval} usata per indicare valori di tempo
+ con la precisione del microsecondo.}
+ \label{fig:sys_timeval_struct}
+\end{figure}
+
+Oltre ad \func{utimes} su Linux sono presenti altre due funzioni,\footnote{le
+ due funzioni non sono definite in nessuno standard, ma sono presenti, oltre
+ che su Linux, anche su BSD.} \funcd{futimes} e \funcd{lutimes}, che
+consentono rispettivamente di effettuare la modifica utilizzando un file
+già aperto o di eseguirla direttamente su un link simbolico. I relativi
+prototipi sono:
+\begin{functions}
+ \headdecl{sys/time.h}
+
+ \funcdecl{int futimes(int fd, const struct timeval tv[2])} Cambia i tempi
+ di un file già aperto specificato tramite il file descriptor \param{fd}.
+
+ \funcdecl{int lutimes(const char *filename, const struct timeval tv[2])}
+ Cambia i tempi di \param{filename} anche se questo è un link simbolico.
+
+
+ \bodydesc{Le funzioni restituiscono zero in caso di successo e $-1$ per un
+ errore, nel qual caso \var{errno} assumerà gli stessi valori di
+ \func{utimes}, con in più per \func{futimes}:
+ \begin{errlist}
+ \item[\errcode{EBADF}] \param{fd} non è un file descriptor.
+ \item[\errcode{ENOSYS}] il filesystem \texttt{/proc} non è accessibile.
+ \end{errlist}}
+\end{functions}
+
+Le due funzioni anno lo stesso comportamento di \texttt{utimes} e richiedono
+gli stessi privilegi per poter operare, la differenza è che con \func{futimes}
+si può indicare il file su cui operare facendo riferimento al relativo file
+descriptor mentre con \func{lutimes} nel caso in cui \param{filename} sia un
+link simbolico saranno modificati i suoi tempi invece di quelli del file a cui
+esso punta.
+
+Nonostante il kernel, come accennato, supporti risoluzioni dei tempi dei file
+fino al nanosecondo, le funzioni fin qui esaminate non consentono di impostare
+valori con questa precisione. Per questo sono state introdotte due nuove
+funzioni, \funcd{futimens} e \func{utimensat}, in grado di eseguire questo
+compito; i rispettivi prototipi sono:
+\begin{functions}
+ \headdecl{sys/time.h}
+
+ \funcdecl{futimens(int fd, const struct timespec times[2])} Cambia i tempi
+ di un file già aperto, specificato dal file descriptor \param{fd}.
+
+ \funcdecl{int utimensat(int dirfd, const char *pathname, const struct
+ timespec times[2], int flags)} Cambia i tempi del file \param{pathname}.
+
+
+ \bodydesc{Le funzioni restituiscono zero in caso di successo e $-1$ per un
+ errore, nel qual caso \var{errno} assumerà gli stessi valori di
+ \func{utimes}, con in più per \func{futimes}:
+ \begin{errlist}
+ \item[\errcode{EBADF}] \param{fd} non è un file descriptor.
+ \item[\errcode{ENOSYS}] il filesystem \texttt{/proc} non è accessibile.
+ \end{errlist}}
+\end{functions}
+
+Entrambe le funzioni utilizzano per indicare i valori dei tempi un
+vettore \param{times} di due strutture \struct{timespec} che permette di
+specificare un valore di tempo con una precisione fino al nanosecondo, la cui
+definizione è riportata in fig.~\ref{fig:sys_timespec_struct}.