+\begin{funcproto}{
+\fhead{sys/stat.h}
+\fhead{sys/types.h}
+\fdecl{int mkdir(const char *dirname, mode\_t mode)}
+\fdesc{Crea una nuova directory.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] non c'è il permesso di scrittura per la directory in
+ cui si vuole inserire la nuova directory o di attraversamento per le
+ directory al di sopra di essa.
+ \item[\errcode{EEXIST}] un file o una directory o un collegamento simbolico
+ con quel nome esiste già.
+ \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 \errval{EFAULT}, \errval{ELOOP}, \errval{ENAMETOOLONG},
+ \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, \errval{EPERM},
+ \errval{EROFS} nel loro significato generico.}
+\end{funcproto}
+
+La funzione crea una nuova directory vuota, che contiene cioè solo le due voci
+standard presenti in ogni directory (``\file{.}'' e ``\file{..}''), con il
+nome indicato dall'argomento \param{dirname}.
+
+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 illustrato in
+sez.~\ref{sec:file_ownership_management}.
+
+Come accennato in precedenza per eseguire la cancellazione di una directory è
+necessaria una specifica funzione di sistema, \funcd{rmdir}, il suo prototipo
+è:
+
+\begin{funcproto}{
+\fhead{sys/stat.h}
+\fdecl{int rmdir(const char *dirname)}
+\fdesc{Cancella una directory.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] 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 o un \textit{mount point}.
+ \item[\errcode{EINVAL}] si è usato ``\texttt{.}'' come ultimo componente
+ di \param{dirname}.
+ \item[\errcode{EPERM}] il filesystem non supporta la cancellazione di
+ directory, oppure la directory che contiene \param{dirname} ha lo
+ \textit{sticky bit} impostato e non si è i proprietari della directory o
+ non si hanno privilegi amministrativi.
+ \end{errlist}
+ ed inoltre \errval{EFAULT}, \errval{ELOOP}, \errval{ENAMETOOLONG},
+ \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, \errcode{ENOTEMPTY} e
+ \errval{EROFS} nel loro significato generico.}
+\end{funcproto}
+
+
+La funzione cancella la directory \param{dirname}, che deve essere vuota, la
+directory deve cioè contenere le due voci standard ``\file{.}'' e
+``\file{..}'' e niente altro. Il nome può essere indicato con un
+\textit{pathname} assoluto o relativo, ma si deve fare riferimento al nome
+nella directory genitrice, questo significa che \textit{pathname} terminanti
+in ``\file{.}'' e ``\file{..}'' anche se validi in altri contesti, causeranno
+il fallimento della funzione.
+
+Inoltre per eseguire la cancellazione, oltre ad essere vuota, occorre anche
+che la directory non sia utilizzata, questo vuol dire anche che non deve
+essere la directory di lavoro (vedi sez.~\ref{sec:file_work_dir}) o la
+directory radice (vedi sez.~\ref{sec:file_chroot}) di nessun processo, od
+essere utilizzata come \textit{mount point}.
+
+Se la directory cancellata risultasse aperta in qualche processo per una
+lettura dei suoi contenuti (vedi sez.~\ref{sec:file_dir_read}), pur
+scomparendo dal filesystem e non essendo più possibile accedervi o crearvi
+altri file, le risorse ad essa associate verrebbero disallocate solo alla
+chiusura di tutti questi ulteriori riferimenti.
+
+
+\subsection{Lettura e scansione delle directory}
+\label{sec:file_dir_read}
+
+Benché le directory alla fine non siano altro che dei file che contengono
+delle liste di nomi associati ai relativi \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_close} 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 prevede una apposita
+funzione per la lettura delle directory.
+
+\itindbeg{directory~stream}
+
+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 \textit{file stream} dell'interfaccia standard ANSI C che vedremo in
+sez.~\ref{sec:files_std_interface}. La prima funzione di questa interfaccia è
+\funcd{opendir}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{dirent.h}
+\fdecl{DIR *opendir(const char *dirname)}
+\fdesc{Apre un \textit{directory stream}.}
+}
+{La funzione ritorna un puntatore al \textit{directory stream} in caso di
+ successo e \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno
+ dei valori \errval{EACCES}, \errval{EMFILE}, \errval{ENFILE},
+ \errval{ENOENT}, \errval{ENOMEM} e \errval{ENOTDIR} nel loro significato
+ generico.}
+\end{funcproto}
+
+La funzione apre un \textit{directory stream} per la directory
+\param{dirname}, ritornando il puntatore ad un oggetto di tipo \typed{DIR} (che
+è il tipo opaco usato dalle librerie per gestire i \textit{directory stream})
+da usare per tutte le operazioni successive, la funzione inoltre posiziona lo
+\textit{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 (vedi
+sez.~\ref{sec:file_fd}) sottostante, sul quale vengono compiute le
+operazioni. Questo viene sempre aperto impostando il flag di
+\textit{close-on-exec} (si ricordi quanto detto in sez.~\ref{sec:proc_exec}),
+così da evitare che resti aperto in caso di esecuzione di un altro programma.
+
+Nel caso in cui sia necessario conoscere il 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 la \acr{glibc} ma non presente in POSIX fino alla revisione
+ POSIX.1-2008, per questo per poterla utilizzare fino alla versione 2.10
+ della \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{funcproto}{
+\fhead{sys/types.h}
+\fhead{dirent.h}
+\fdecl{int dirfd(DIR *dir)}
+\fdesc{Legge il file descriptor associato ad un \textit{directory stream}.}
+}
+{La funzione ritorna un valore positivo corrispondente al file descriptor in
+ caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà
+ uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{dir} non è un puntatore ad un
+ \textit{directory stream}.
+ \item[\errcode{ENOTSUP}] l'implementazione non supporta l'uso di un file
+ descriptor per la directory.
+ \end{errlist}
+}
+\end{funcproto}
+
+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 della \acr{glibc}, ed è stata introdotta nello standard
+ POSIX solo a partire dalla revisione POSIX.1-2008, prima della versione 2.10
+ della \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{funcproto}{
+\fhead{sys/types.h}
+\fhead{dirent.h}
+\fdecl{DIR *fdopendir(int fd)}
+\fdesc{Associa un \textit{directory stream} ad un file descriptor.}
+}
+{La funzione ritorna un puntatore al \textit{directory stream} in caso di
+ successo e \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno
+ dei valori \errval{EBADF} o \errval{ENOMEM} nel loro significato generico.}
+\end{funcproto}
+
+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 attraverso il \textit{directory stream} con \func{closedir} e non
+direttamente. Si tenga presente inoltre che \func{fdopendir} non modifica lo
+stato di un eventuale flag di \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 cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{dirent.h}
+\fdecl{struct dirent *readdir(DIR *dir)}
+\fdesc{Legge una voce dal \textit{directory stream}.}
+}
+{La funzione ritorna il puntatore alla struttura contenente i dati in caso di
+ successo e \val{NULL} per un errore o se si è raggiunta la fine dello
+ \textit{stream}. Il solo codice di errore restituito in \var{errno} è
+ \errval{EBADF} qualora \param{dir} non indichi un \textit{directory stream}
+ valido.}
+\end{funcproto}
+
+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, che viene segnalata dalla
+restituzione di \val{NULL} come valore di ritorno. Si può distinguere questa
+condizione da un errore in quanto in questo caso \var{errno} non verrebbe
+modificata.
+
+I dati letti da \func{readdir} 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 non è rientrante e restituisce il puntatore ad
+una struttura allocata staticamente, che 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 rientrante,
+\funcd{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 \textit{thread}, il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{dirent.h}
+\fdecl{int readdir\_r(DIR *dir, struct dirent *entry, struct dirent **result)}
+\fdesc{Legge una voce dal \textit{directory stream}.}
+}
+{La funzione ritorna $0$ in caso di successo ed un numero positivo per un
+ errore, nel qual caso \var{errno} assumerà gli stessi valori di
+ \func{readdir}.}
+\end{funcproto}
+
+La funzione restituisce in \param{result} come \textit{value result argument}
+l'indirizzo della struttura \struct{dirent} dove sono stati salvati i dati,
+che deve essere allocata dal chiamante, ed il cui indirizzo deve essere
+indicato con l'argomento \param{entry}. Se si è raggiunta la fine del
+\textit{directory stream} invece in \param{result} viene restituito il valore
+\val{NULL}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.8\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}
+
+% Lo spazio per la \struct{dirent} dove vengono restituiti i dati della
+% directory deve essere allocato a cura del chiamante, dato che la dimensione
+
+
+I vari campi di \struct{dirent} contengono le informazioni relative alle voci
+presenti nella directory. Sia BSD che SVr4 che POSIX.1-2001\footnote{il
+ vecchio standard POSIX prevedeva invece solo la presenza del campo
+ \var{d\_fileno}, identico \var{d\_ino}, che in Linux era definito come alias
+ di quest'ultimo, mentre il campo \var{d\_name} era considerato dipendente
+ dall'implementazione.} prevedono che siano sempre presenti il campo
+\var{d\_name}, che contiene il nome del file nella forma di una stringa
+terminata da uno zero, 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. Come si può evincere da fig.~\ref{fig:file_dirent_struct} nel caso di
+Linux sono pertanto definite le macro \macrod{\_DIRENT\_HAVE\_D\_TYPE},
+\macrod{\_DIRENT\_HAVE\_D\_OFF} e \macrod{\_DIRENT\_HAVE\_D\_RECLEN}, mentre non
+è definita la macro \macrod{\_DIRENT\_HAVE\_D\_NAMLEN}.
+
+Dato che possono essere presenti campi opzionali e che lo standard
+POSIX.1-2001 non specifica una dimensione definita per il nome dei file (che
+può variare a seconda del filesystem), ma solo un limite superiore pari a
+\const{NAME\_MAX} (vedi tab.~\ref{tab:sys_file_macro}), in generale per
+allocare una struttura \struct{dirent} in maniera portabile occorre eseguire
+un calcolo per ottenere le dimensioni appropriate per il proprio
+sistema.\footnote{in SVr4 la lunghezza del campo è definita come
+ \code{NAME\_MAX+1} che di norma porta al valore di 256 byte usato anche in
+ fig.~\ref{fig:file_dirent_struct}.} Lo standard però richiede che il campo
+\var{d\_name} sia sempre l'ultimo della struttura, questo ci consente di
+ottenere la dimensione della prima parte con la macro di utilità generica
+\macro{offsetof}, che si può usare con il seguente prototipo:
+
+{\centering
+\vspace{3pt}
+\begin{funcbox}{
+\fhead{stddef.h}
+\fdecl{size\_t \macrod{offsetof}(type, member)}
+\fdesc{Restituisce la posizione del campo \param{member} nella
+ struttura \param{type}.}
+}
+\end{funcbox}
+}
+
+Ottenuta allora con \code{offsetof(struct dirent, d\_name)} la dimensione
+della parte iniziale della struttura, basterà sommarci la dimensione massima
+dei nomi dei file nel filesystem che si sta usando, che si può ottenere
+attraverso la funzione \func{pathconf} (per la quale si rimanda a
+sez.~\ref{sec:sys_file_limits}) più un ulteriore carattere per la terminazione
+della stringa.
+
+Per quanto riguarda il significato dei campi opzionali, il campo \var{d\_type}
+indica il tipo di file (se \textit{fifo}, directory, collegamento simbolico,
+ecc.), e consente di evitare una successiva chiamata a \func{lstat} (vedi
+sez.~\ref{sec:file_stat}) 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 \acr{Btrfs}, \acr{ext2}, \acr{ext3}, e
+\acr{ext4}), per gli altri si otterrà sempre il valore
+\const{DT\_UNKNOWN}.\footnote{inoltre fino alla versione 2.1 della
+ \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}.}
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Valore} & \textbf{Tipo di file} \\
+ \hline
+ \hline
+ \constd{DT\_UNKNOWN} & Tipo sconosciuto.\\
+ \constd{DT\_REG} & File normale.\\
+ \constd{DT\_DIR} & Directory.\\
+ \constd{DT\_LNK} & Collegamento simbolico.\\
+ \constd{DT\_FIFO} & \textit{Fifo}.\\
+ \constd{DT\_SOCK} & Socket.\\
+ \constd{DT\_CHR} & Dispositivo a caratteri.\\
+ \constd{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 la conversione da e verso l'analogo valore mantenuto dentro il campo
+\var{st\_mode} di \struct{stat} (vedi fig.~\ref{fig:file_stat_struct}) sono
+definite anche due macro di conversione, \macro{IFTODT} e \macro{DTTOIF}:
+
+{\centering
+\vspace{3pt}
+\begin{funcbox}{
+\fhead{dirent.h}
+\fdecl{int \macrod{IFTODT}(mode\_t MODE)}
+\fdesc{Converte il tipo di file dal formato di \var{st\_mode} a quello di
+ \var{d\_type}.}
+\fdecl{mode\_t \macrod{DTTOIF}(int DTYPE)}
+\fdesc{Converte il tipo di file dal formato di \var{d\_type} a quello di
+ \var{st\_mode}.}
+}
+\end{funcbox}
+}
+
+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 \textit{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{funcproto}{
+\fhead{dirent.h}
+\fdecl{void seekdir(DIR *dir, off\_t offset)}
+\fdesc{Cambia la posizione all'interno di un \textit{directory stream}.}
+}
+{La funzione non ritorna niente e non imposta errori.}
+\end{funcproto}
+
+La funzione non ritorna nulla e non segnala errori, è però necessario che il
+valore dell'argomento \param{offset} sia valido per lo
+\textit{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 cui prototipo
+è:\footnote{prima della \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{funcproto}{
+\fhead{dirent.h}
+\fdecl{long telldir(DIR *dir)}
+\fdesc{Ritorna la posizione corrente in un \textit{directory stream}.}
+}
+{La funzione ritorna la posizione corrente nello \textit{stream} (un numero
+ positivo) in caso di successo e $-1$ per un errore, nel qual caso
+ \var{errno} assume solo il valore di \errval{EBADF}, corrispondente ad un
+ valore errato per \param{dir}. }
+\end{funcproto}
+
+La sola funzione di posizionamento per un \textit{directory stream} prevista
+originariamente dallo standard POSIX è \funcd{rewinddir}, che riporta la
+posizione a quella iniziale; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{dirent.h}
+\fdecl{void rewinddir(DIR *dir)}
+\fdesc{Si posiziona all'inizio di un \textit{directory stream}.}
+}
+{La funzione non ritorna niente e non imposta errori.}
+\end{funcproto}
+
+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{funcproto}{
+\fhead{sys/types.h}
+\fhead{dirent.h}
+\fdecl{int closedir(DIR *dir)}
+\fdesc{Chiude un \textit{directory stream}.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assume solo il valore \errval{EBADF}.}
+\end{funcproto}
+
+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{funcproto}{
+\fhead{dirent.h}
+\fdecl{int scandir(const char *dir, struct dirent ***namelist, \\
+\phantom{int scandir(}int(*filter)(const struct dirent *), \\
+\phantom{int scandir(}int(*compar)(const struct dirent **, const struct dirent **))}
+\fdesc{Esegue una scansione di un \textit{directory stream}.}
+}
+{La funzione ritorna il numero di voci trovate in caso di successo e $-1$ per
+ un errore, nel qual caso \var{errno} può assumere solo il valore
+ \errval{ENOMEM}.}
+\end{funcproto}
+
+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, passata con
+l'argomento \param{filter}, e l'ordinamento di tutte le voci selezionate,
+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 \param{filter} non
+viene fatta nessuna selezione e si ottengono tutte le voci presenti.
+
+Le voci selezionate possono essere riordinate tramite \funcm{qsort}, le
+modalità del riordinamento possono essere personalizzate usando la funzione
+\param{compar} come criterio di ordinamento di \funcm{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 \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.}
+
+\itindend{directory~stream}
+
+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{funcproto}{
+\fhead{dirent.h}
+\fdecl{int alphasort(const void *a, const void *b)}
+\fdecl{int versionsort(const void *a, const void *b)}
+\fdesc{Riordinano le voci di \textit{directory stream}.}
+}
+{Le funzioni restituiscono un valore minore, uguale o maggiore di zero qualora
+ il primo argomento sia rispettivamente minore, uguale o maggiore del secondo
+ e non forniscono errori.}
+\end{funcproto}
+
+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}; la glibc usa 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. La \acr{glibc} prevede come
+estensione\footnote{la \acr{glibc}, a partire dalla versione 2.1, effettua
+ anche l'ordinamento alfabetico tenendo conto delle varie localizzazioni,
+ usando \funcm{strcoll} al posto di \funcm{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}[!htb]
+ \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 può essere
+trovato coi sorgenti allegati alla guida 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
+\myfunc{dir\_scan} 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 \myfunc{dir\_scan} 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}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/dir_scan.c}
+ \end{minipage}
+ \caption{Codice della funzione di scansione di una directory contenuta nel
+ file \file{dir\_scan.c}.}
+ \label{fig:file_dirscan}
+\end{figure}
+
+Tutto il grosso del lavoro è svolto dalla funzione \myfunc{dir\_scan},
+riportata in fig.~\ref{fig:file_dirscan}. La funzione è volutamente generica e
+permette di eseguire una funzione, passata come secondo argomento, su tutte le
+voci di una directory. La funzione inizia con l'aprire (\texttt{\small
+ 18-22}) uno \textit{stream} sulla directory passata come primo argomento,
+stampando un messaggio in caso di errore.
+
+Il passo successivo (\texttt{\small 23-24}) è cambiare directory di lavoro
+(vedi sez.~\ref{sec:file_work_dir}), usando in sequenza le funzioni
+\func{dirfd} e \func{fchdir} (in realtà si sarebbe potuto usare direttamente
+\func{chdir} su \var{dirname}), in modo che durante il successivo ciclo
+(\texttt{\small 26-30}) sulle singole voci dello \textit{stream} ci si trovi
+all'interno della directory.\footnote{questo è essenziale al funzionamento
+ della funzione \code{do\_ls}, e ad ogni funzione che debba usare il campo
+ \var{d\_name}, in quanto i nomi dei file memorizzati all'interno di una
+ struttura \struct{dirent} sono sempre relativi alla directory in questione,
+ e senza questo posizionamento non si sarebbe potuto usare \func{stat} per
+ ottenere le dimensioni.}
+
+Avendo usato lo stratagemma di fare eseguire tutte le manipolazioni necessarie
+alla funzione passata come secondo argomento, il ciclo di scansione della
+directory è molto semplice; si legge una voce alla volta (\texttt{\small 26})
+all'interno di una istruzione di \code{while} e fintanto che si riceve una
+voce valida, cioè un puntatore diverso da \val{NULL}, si esegue
+(\texttt{\small 27}) la funzione di elaborazione \var{compare} (che nel nostro
+caso sarà \code{do\_ls}), ritornando con un codice di errore (\texttt{\small
+ 28}) qualora questa presenti una anomalia, identificata da un codice di
+ritorno negativo. Una volta terminato il ciclo la funzione si conclude con la
+chiusura (\texttt{\small 31}) dello \textit{stream}\footnote{nel nostro caso,
+ uscendo subito dopo la chiamata, questo non servirebbe, in generale però
+ l'operazione è necessaria, dato che la funzione può essere invocata molte
+ volte all'interno dello stesso processo, per cui non chiudere i
+ \textit{directory stream} comporterebbe un consumo progressivo di risorse,
+ con conseguente rischio di esaurimento delle stesse.} e la restituzione
+(\texttt{\small 32}) del codice di operazioni concluse con successo.
+
+
+
+\subsection{La directory di lavoro}
+\label{sec:file_work_dir}
+
+\index{directory~di~lavoro|(}
+
+Come accennato in sez.~\ref{sec:proc_fork} a ciascun processo è associata una
+directory nell'albero dei file,\footnote{questa viene mantenuta all'interno
+ dei dati della sua \kstruct{task\_struct} (vedi
+ fig.~\ref{fig:proc_task_struct}), più precisamente nel campo \texttt{pwd}
+ della sotto-struttura \kstruct{fs\_struct}.} che è chiamata
+\textsl{directory corrente} o \textsl{directory di lavoro} (in inglese
+\textit{current working directory}). La directory di lavoro è quella da cui
+si parte quando un \textit{pathname} è espresso in forma relativa, dove il
+``\textsl{relativa}'' fa riferimento appunto a questa directory.
+
+Quando un utente effettua il login, questa directory viene impostata alla
+\textit{home directory} del suo account. Il comando \cmd{cd} della shell
+consente di cambiarla a piacere, spostandosi da una directory ad un'altra, il
+comando \cmd{pwd} la stampa sul terminale. Siccome la directory di lavoro
+resta la stessa quando viene creato un processo figlio (vedi
+sez.~\ref{sec:proc_fork}), la directory di lavoro della shell diventa anche la
+directory di lavoro di qualunque comando da essa lanciato.
+
+Dato che è il kernel che tiene traccia dell'\textit{inode} della directory di
+lavoro di ciascun processo, per ottenerne il \textit{pathname} occorre usare
+una apposita funzione, \funcd{getcwd},\footnote{con Linux \func{getcwd} è una
+ \textit{system call} dalla versione 2.1.9, in precedenza il valore doveva
+ essere ottenuto tramite il filesystem \texttt{/proc} da
+ \procfile{/proc/self/cwd}.} il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{char *getcwd(char *buffer, size\_t size)}
+\fdesc{Legge il \textit{pathname} della directory di lavoro corrente.}
+}
+{La funzione ritorna il puntatore a \param{buffer} in caso di successo e
+ \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] manca il permesso di lettura o di attraversamento su
+ uno dei componenti del \textit{pathname} (cioè su una delle directory
+ superiori alla corrente).
+ \item[\errcode{EINVAL}] l'argomento \param{size} è zero e \param{buffer} non
+ è nullo.
+ \item[\errcode{ENOENT}] la directory di lavoro è stata eliminata.
+ \item[\errcode{ERANGE}] l'argomento \param{size} è più piccolo della
+ lunghezza del \textit{pathname}.
+ \end{errlist}
+ ed inoltre \errcode{EFAULT} ed \errcode{ENOMEM} nel loro significato
+ generico.}
+\end{funcproto}
+
+La funzione restituisce il \textit{pathname} completo della directory di
+lavoro corrente nella stringa puntata da \param{buffer}, che deve essere
+precedentemente allocata, per una dimensione massima di \param{size}. Il
+buffer deve essere sufficientemente largo da poter contenere il
+\textit{pathname} completo più lo zero di terminazione della stringa. Qualora
+esso ecceda le dimensioni specificate con \param{size} la funzione restituisce
+un errore.
+
+A partire dal kernel Linux 2.6.36 il nome può avere come prefisso la stringa
+\texttt{(unreachable)} se la directory di lavoro resta fuori dalla directory
+radice del processo dopo un \func{chroot} (torneremo su questi argomenti in
+sez.~\ref{sec:file_chroot}); pertanto è sempre opportuno controllare il primo
+carattere della stringa restituita dalla funzione per evitare di interpretare
+mare un \textit{pathname} irraggiungibile.
+
+Come estensione allo standard POSIX.1, supportata da Linux e dalla
+\acr{glibc}, si può anche specificare un puntatore nullo come \param{buffer}
+nel qual caso la stringa sarà allocata automaticamente per una dimensione pari
+a \param{size} qualora questa sia diversa da zero, o della lunghezza esatta
+del \textit{pathname} altrimenti. In questo caso ci si deve ricordare di
+disallocare la stringa con \func{free} una volta cessato il suo utilizzo.
+
+Un uso comune di \func{getcwd} è quello di salvarsi la directory di lavoro
+all'avvio del programma per poi potervi tornare in un tempo successivo, un
+metodo alternativo più veloce, se non si è a corto di file descriptor, è
+invece quello di aprire all'inizio la directory corrente (vale a dire
+``\texttt{.}'') e tornarvi in seguito con \func{fchdir}.
+
+Di questa funzione esiste una versione alternativa per compatibilità
+all'indietro con BSD, \funcm{getwd}, che non prevede l'argomento \param{size}
+e quindi non consente di specificare la dimensione di \param{buffer} che
+dovrebbe essere allocato in precedenza ed avere una dimensione sufficiente
+(per BSD maggiore \const{PATH\_MAX}, che di solito 256 byte, vedi
+sez.~\ref{sec:sys_limits}). Il problema è che su Linux non esiste una
+dimensione superiore per la lunghezza di un \textit{pathname}, per cui non è
+detto che il buffer sia sufficiente a contenere il nome del file, e questa è
+la ragione principale per cui questa funzione è deprecata, e non la tratteremo.
+
+Una seconda funzione usata per ottenere la directory di lavoro è
+\funcm{get\_current\_dir\_name} (la funzione è una estensione GNU e presente
+solo nella \acr{glibc}) che non prende nessun argomento ed è sostanzialmente
+equivalente ad una \code{getcwd(NULL, 0)}, con la differenza che se
+disponibile essa ritorna il valore della variabile di ambiente \envvar{PWD},
+che essendo costruita dalla shell può contenere un \textit{pathname}
+comprendente anche dei collegamenti simbolici. Usando \func{getcwd} infatti,
+essendo il \textit{pathname} ricavato risalendo all'indietro l'albero della
+directory, si perderebbe traccia di ogni passaggio attraverso eventuali
+collegamenti simbolici.
+
+Per cambiare la directory di lavoro si può usare la funzione di sistema
+\funcd{chdir}, equivalente del comando di shell \cmd{cd}, il cui nome sta
+appunto per \textit{change directory}, il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int chdir(const char *pathname)}
+\fdesc{Cambia la directory di lavoro per \textit{pathname}.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] manca il permesso di ricerca su uno dei componenti
+ di \param{pathname}.
+ \item[\errcode{ENAMETOOLONG}] il nome indicato in \param{path} è troppo lungo.
+ \item[\errcode{ENOTDIR}] non si è specificata una directory.
+ \end{errlist}
+ ed inoltre \errval{EFAULT}, \errval{EIO}, \errval{ELOOP}, \errval{ENOENT} e
+ \errval{ENOMEM} nel loro significato generico.}
+\end{funcproto}
+
+La funzione cambia la directory di lavoro in \param{pathname} ed
+ovviamente \param{pathname} deve indicare una directory per la quale si hanno
+i permessi di accesso.
+
+Dato che ci si può riferire ad una directory anche tramite un file descriptor,
+per cambiare directory di lavoro è disponibile anche la funzione di sistema
+\funcd{fchdir}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int fchdir(int fd)}
+\fdesc{Cambia la directory di lavoro per file descriptor.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà i valori \errval{EBADF} o \errval{EACCES} nel loro
+ significato generico.}
+\end{funcproto}
+
+La funzione è identica a \func{chdir}, ma prende come argomento un file
+descriptor \param{fd} invece di un \textit{pathname}. Anche in questo
+caso \param{fd} deve essere un file descriptor valido che fa riferimento ad
+una directory. Inoltre l'unico errore di accesso possibile (tutti gli altri
+sarebbero occorsi all'apertura di \param{fd}), è quello in cui il processo non
+ha il permesso di attraversamento alla directory specificata da \param{fd}.
+
+\index{directory~di~lavoro|)}
+
+
+\subsection{La creazione dei \textsl{file speciali}}
+\label{sec:file_mknod}
+
+\index{file!di~dispositivo|(}
+\index{file!speciali|(}
+
+Finora abbiamo parlato esclusivamente di file, directory e collegamenti
+simbolici, ma in sez.~\ref{sec:file_file_types} abbiamo visto che il sistema
+prevede anche degli altri tipi di file, che in genere vanno sotto il nome
+generico di \textsl{file speciali}, come i file di dispositivo, le
+\textit{fifo} ed i socket.
+
+La manipolazione delle caratteristiche di questi file speciali, il cambiamento
+di nome o la loro cancellazione può essere effettuata con le stesse funzioni
+che operano sugli altri file, ma quando li si devono creare sono necessarie,
+come per le directory, delle funzioni apposite. La prima di queste è la
+funzione di sistema \funcd{mknod}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/stat.h}
+\fhead{fcntl.h}
+\fhead{unistd.h}
+\fdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)}
+\fdesc{Crea un file speciale sul filesystem.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EEXIST}] \param{pathname} esiste già o è un collegamento
+ simbolico.
+ \item[\errcode{EINVAL}] il valore di \param{mode} non indica un file, una
+ \textit{fifo}, un socket o un dispositivo.
+ \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.
+ \end{errlist}
+ ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{ELOOP},
+ \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOSPC},
+ \errval{ENOTDIR} e \errval{EROFS} nel loro significato generico.}
+\end{funcproto}
+
+La funzione permette di creare un \textit{inode} di tipo generico sul
+filesystem, e viene in genere utilizzata per creare i file di dispositivo, ma
+si può usare anche per creare qualunque tipo di file speciale ed anche file
+regolari. L'argomento \param{mode} specifica sia il tipo di file che si vuole
+creare che i relativi permessi, secondo i valori riportati in
+tab.~\ref{tab:file_mode_flags}, che vanno combinati con un OR aritmetico. I
+permessi sono comunque modificati nella maniera usuale dal valore di
+\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 \textit{fifo};\footnote{con Linux la funzione non può essere usata per
+ creare directory o collegamenti simbolici, si dovranno usare le funzioni
+ \func{mkdir} e \func{symlink} a questo dedicate.} un valore diverso
+comporterà l'errore \errcode{EINVAL}. Inoltre \param{pathname} non deve
+esistere, neanche come collegamento simbolico.
+
+Qualora si sia specificato in \param{mode} un file di dispositivo (vale a dire
+o \const{S\_IFBLK} o \const{S\_IFCHR}), il valore di \param{dev} dovrà essere
+usato per indicare a quale dispositivo si fa riferimento, altrimenti il suo
+valore verrà ignorato. Solo l'amministratore può creare un file di
+dispositivo usando questa funzione (il processo deve avere la capacità
+\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 \textit{fifo}, ma comunque deprecata essendo utilizzabile a tale scopo
+ la specifica \func{mkfifo}.} l'uso per la creazione di un file ordinario, di
+una \textit{fifo} o di un socket è consentito anche agli utenti normali.
+
+Gli \textit{inode} creati con \func{mknod} apparterranno al proprietario e al
+gruppo del processo (usando \ids{UID} e \ids{GID} del gruppo effettivo) che li
+ha creati a meno non sia presente 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
+l'\textit{inode}, nel qual caso per il gruppo verrà usato il \ids{GID} del
+proprietario della directory.
+
+\itindbeg{major~number}
+\itindbeg{minor~number}
+
+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 \textit{major
+ number} e \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 \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 uno dei dischi presenti) si usa invece il \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 \textit{major
+ number} e 20 bit per il \textit{minor number}. La transizione però ha
+comportato il fatto che \type{dev\_t} è diventato un 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 \headfiled{sys/sysmacros.h},\footnote{se si
+ usa la \acr{glibc} dalla versione 2.3.3 queste macro sono degli alias alle
+ versioni specifiche di questa libreria, \macrod{gnu\_dev\_major},
+ \macrod{gnu\_dev\_minor} e \macrod{gnu\_dev\_makedev} che si possono usare
+ direttamente, al costo di una minore portabilità.} che viene automaticamente
+incluso quando si include \headfile{sys/types.h}. Si possono pertanto ottenere
+i valori del \textit{major number} e \textit{minor number} di un dispositivo
+rispettivamente con le macro \macro{major} e \macro{minor}:
+
+{\centering
+\vspace{3pt}
+\begin{funcbox}{
+\fhead{sys/types.h}
+\fdecl{int \macrod{major}(dev\_t dev)}
+\fdesc{Restituisce il \textit{major number} del dispositivo \param{dev}.}
+\fdecl{int \macrod{minor}(dev\_t dev)}
+\fdesc{Restituisce il \textit{minor number} del dispositivo \param{dev}.}
+}
+\end{funcbox}
+}
+
+\noindent mentre una volta che siano noti \textit{major number} e
+\textit{minor number} si potrà costruire il relativo identificativo con la
+macro \macro{makedev}:
+
+{\centering
+\vspace{3pt}
+\begin{funcbox}{
+\fhead{sys/types.h}
+\fdecl{dev\_t \macrod{makedev}(int major, int minor)}
+\fdesc{Dati \textit{major number} e \textit{minor number} restituisce
+ l'identificativo di un dispositivo.}
+}
+\end{funcbox}
+}
+
+
+\itindend{major~number}
+\itindend{minor~number}
+\index{file!di~dispositivo|)}
+
+Dato che la funzione di sistema \func{mknod} presenta diverse varianti nei
+vari sistemi unix-like, lo standard POSIX.1-2001 la dichiara portabile solo in
+caso di creazione delle \textit{fifo}, ma anche in questo caso alcune
+combinazioni degli argomenti restano non specificate, per cui nello stesso
+standard è stata introdotta una funzione specifica per creare una
+\textit{fifo} deprecando l'uso di \func{mknod} a tale riguardo. La funzione è
+\funcd{mkfifo} ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/stat.h}
+\fdecl{int mkfifo(const char *pathname, mode\_t mode)}
+\fdesc{Crea una \textit{fifo}.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà \errval{EACCES}, \errval{EEXIST},
+ \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOSPC}, \errval{ENOTDIR} e
+ \errval{EROFS} nel loro significato generico.}
+\end{funcproto}
+
+La funzione crea la \textit{fifo} \param{pathname} con i
+permessi \param{mode}. Come per \func{mknod} il file \param{pathname} non deve
+esistere (neanche come collegamento simbolico); al solito i permessi
+specificati da \param{mode} vengono modificati dal valore di \textit{umask}
+(vedi sez.~\ref{sec:file_perm_management}).
+
+\index{file!speciali|)}
+
+
+\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 \textit{race
+ condition} (si ricordi quanto visto in sez.~\ref{sec:proc_race_cond}).
+
+\itindbeg{symlink~attack}
+
+Molti problemi di sicurezza derivano proprio da una creazione non accorta di
+file temporanei che lascia aperta questa \textit{race condition}. Un
+attaccante allora potrà sfruttarla con quello che viene chiamato
+``\textit{symlink attack}'' dove nell'intervallo fra la generazione di un nome
+e l'accesso allo stesso, viene creato un collegamento simbolico con quel nome
+verso un file diverso, ottenendo, se il programma sotto attacco ne ha la
+capacità, un accesso privilegiato.\footnote{dal kernel 3.6 sono state
+ introdotte delle contromisure, illustrate in
+ sez.~\ref{sec:procadv_security_misc}, che rendono impraticabili questo tipo
+ di attacchi, ma questa non è una buona scusa per ignorare il problema.}
+
+\itindend{symlink~attack}
+
+La \acr{glibc} provvede 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{funcproto}{
+\fhead{stdio.h}
+\fdecl{char *tmpnam(char *string)}
+\fdesc{Genera un nome univoco per un file temporaneo.}
+}
+{La funzione ritorna il puntatore alla stringa con il nome in caso di successo
+ e \val{NULL} in caso di fallimento, non sono definiti errori.}
+\end{funcproto}
+
+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 \constd{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 \constd{TMP\_MAX} volte, limite oltre il quale il comportamento è
+indefinito. Al nome viene automaticamente aggiunto come prefisso la directory
+specificata dalla costante \constd{P\_tmpdir}.\footnote{le costanti
+ \const{L\_tmpnam}, \const{P\_tmpdir} e \const{TMP\_MAX} sono definite in
+ \headfile{stdio.h}.}
+
+Di questa funzione esiste una versione rientrante, \funcm{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{funcproto}{
+\fhead{stdio.h}
+\fdecl{char *tempnam(const char *dir, const char *pfx)}
+\fdesc{Genera un nome univoco per un file temporaneo.}
+}
+{La funzione ritorna il puntatore alla stringa con il nome in caso di successo
+ e \val{NULL} per un errore, nel qual caso \var{errno} potrà assumere solo il
+ valore \errval{ENOMEM} qualora fallisca l'allocazione della stringa.}
+\end{funcproto}
+
+La funzione alloca con \code{malloc} la stringa in cui restituisce il nome,
+per cui è sempre 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 \envvar{TMPDIR} (non ha effetto se non è
+ definita o se il programma chiamante è \acr{suid} o \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 con queste funzioni 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 o un collegamento simbolico con lo stesso nome. Per questo
+motivo quando si usa il nome ottenuto da una di queste funzioni occorre sempre
+assicurarsi che non si stia usando un collegamento simbolico e aprire il nuovo
+file in modalità di esclusione (cioè con l'opzione \const{O\_EXCL} per i file
+descriptor o con il flag ``\texttt{x}'' per gli \textit{stream}) che fa
+fallire l'apertura in caso il file sia già esistente. Essendo disponibili
+alternative migliori l'uso di queste funzioni è deprecato.
+
+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{funcproto}{
+\fhead{stdio.h}
+\fdecl{FILE *tmpfile(void)}
+\fdesc{Apre un file temporaneo in lettura/scrittura.}
+}
+{La funzione ritorna il puntatore allo \textit{stream} associato al file
+ temporaneo in caso di successo e \val{NULL} per un errore, nel qual caso
+ \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EEXIST}] non è stato possibile generare un nome univoco.
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+ \end{errlist}
+ ed inoltre \errval{EFAULT}, \errval{EMFILE}, \errval{ENFILE},
+ \errval{ENOSPC}, \errval{EROFS} e \errval{EACCES} nel loro significato
+ generico.}
+\end{funcproto}
+
+
+La funzione restituisce direttamente uno \textit{stream} già aperto (in
+modalità \code{w+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 la \acr{glibc} prima tenta con \const{P\_tmpdir} e poi con
+\file{/tmp}. Questa funzione è rientrante e non soffre di problemi di
+\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 ``\texttt{X}'' che verranno sostituiti da un codice
+unico. La prima delle due è analoga a \func{tmpnam} e genera soltanto un nome
+casuale, il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stlib.h}
+\fdecl{char *mktemp(char *template)}
+\fdesc{Genera un nome univoco per un file temporaneo.}
+}
+{La funzione ritorna il puntatore a \param{template} in caso di successo e
+ \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}.
+ \end{errlist}}
+\end{funcproto}
+
+La funzione 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 \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 \ids{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{funcproto}{
+\fhead{stlib.h}
+\fdecl{int mkstemp(char *template)}
+\fdesc{Apre un file temporaneo.}
+}
+
+{La funzione ritorna il file descriptor in caso di successo e $-1$ per un
+ errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EEXIST}] non è riuscita a creare un file temporaneo, il
+ contenuto di \param{template} è indefinito.
+ \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}.
+ \end{errlist}}
+\end{funcproto}
+
+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_close}), 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 dalla \acr{glibc} 2.0.7, le versioni precedenti della \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
+ \macro{\_GNU\_SOURCE}.} il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{stlib.h}
+\fdecl{int mkostemp(char *template, int flags)}
+\fdesc{Apre un file temporaneo.}
+}
+{La funzione ritorna un file descriptor in caso di successo e $-1$ per un
+ errore, nel qual caso \var{errno} assumerà gli stessi valori di
+ \func{mkstemp}.}
+\end{funcproto}
+\noindent la cui sola differenza è la presenza dell'ulteriore argomento
+\var{flags} che consente di specificare alcuni ulteriori flag (come
+\const{O\_APPEND}, \const{O\_CLOEXEC}, \const{O\_SYNC}, il cui significato
+vedremo in sez.~\ref{sec:file_open_close}) da passare ad \func{open}
+nell'apertura del file.\footnote{si tenga presente che \func{mkostemp}
+ utilizza già \const{O\_CREAT}, \const{O\_EXCL} e \const{O\_RDWR}, che non è
+ il caso di riindicare, dato che ciò potrebbe portare ad errori in altri
+ sistemi operativi.}
+
+Di queste due funzioni sono state poi introdotte, a partire dalla \acr{glibc}
+2.11 due varianti, \funcd{mkstemps} e \funcd{mkostemps}, che consentono di
+indicare anche un suffisso, i loro prototipi sono:
+
+\begin{funcproto}{
+\fhead{stlib.h}
+\fdecl{int mkstemps(char *template, int suffixlen)}
+\fdesc{Apre un file temporaneo.}
+\fdecl{int mkostemps(char *template, int suffixlen, int flags)}
+\fdesc{Apre un file temporaneo.}
+}
+
+{Le funzioni hanno gli stessi valori di ritorno e gli stessi errori di
+ \func{mkstemp} con lo stesso significato, tranne \errval{EINVAL} che viene
+ restituito se \param{template} non è di lunghezza pari ad almeno
+ $6+$\param{suffixlen} ed i 6 caratteri prima del suffisso non sono
+ \code{XXXXXX}.}
+\end{funcproto}
+
+Le due funzioni, un'estensione non standard fornita dalla \acr{glibc}, sono
+identiche a \funcd{mkstemp} e \funcd{mkostemp}, ma consentono di avere un nome
+del file nella forma \texttt{prefissoXXXXXXsuffisso} dove la lunghezza del
+suffisso deve essere indicata con \param{suffixlen}.
+
+Infine con OpenBSD è stata introdotta un'altra funzione simile alle
+precedenti, \funcd{mkdtemp}, che crea invece una directory
+temporanea;\footnote{la funzione è stata introdotta nella \acr{glibc} a
+ partire dalla versione 2.1.91 ed inserita nello standard POSIX.1-2008.} il
+suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stlib.h}
+\fdecl{char *mkdtemp(char *template)}
+\fdesc{Crea una directory temporanea.}
+}
+{La funzione ritorna il puntatore al nome della directory in caso di successo
+ e \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei
+ 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{funcproto}
+
+La funzione crea una directory temporanea il cui nome è ottenuto sostituendo
+le \code{XXXXXX} finali di \param{template} con permessi \code{0700} (si veda
+sez.~\ref{sec:file_perm_overview} per i dettagli). Dato che la creazione della
+directory è sempre atomica i precedenti problemi di \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 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
+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 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 di sistema \funcd{stat}, \funcd{fstat} e \funcd{lstat}, i cui
+prototipi sono:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/stat.h}
+\fhead{unistd.h}
+\fdecl{int stat(const char *file\_name, struct stat *buf)}
+\fdecl{int lstat(const char *file\_name, struct stat *buf)}
+\fdecl{int fstat(int filedes, struct stat *buf)}
+\fdesc{Leggono le informazioni di un file.}
+}
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EOVERFLOW}] il file ha una dimensione che non può essere
+ rappresentata nel tipo \type{off\_t} (può avvenire solo in caso di
+ programmi compilati su piattaforme a 32 bit senza le estensioni
+ (\texttt{-D \_FILE\_OFFSET\_BITS=64}) per file a 64 bit).
+ \end{errlist}
+ ed inoltre \errval{EFAULT} ed \errval{ENOMEM}, per \func{stat} e
+ \func{lstat} anche \errval{EACCES}, \errval{ELOOP}, \errval{ENAMETOOLONG},
+ \errval{ENOENT}, \errval{ENOTDIR}, per \func{fstat} anche \errval{EBADF},
+ nel loro significato generico.}
+\end{funcproto}
+
+La funzione \func{stat} legge le informazioni del file indicato
+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 collegamento 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
+\headfiled{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}).
+
+\begin{figure}[!htb]
+ \footnotesize
+ \centering
+ \begin{minipage}[c]{0.8\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 \headfile{sys/types.h},
+con l'eccezione di \typed{blksize\_t} e \typed{blkcnt\_t} che sono nuovi tipi
+introdotti per rendersi indipendenti dalla piattaforma.
+
+Benché la descrizione dei commenti di fig.~\ref{fig:file_stat_struct} sia
+abbastanza chiara, vale la pena illustrare maggiormente il significato dei
+campi di \struct{stat} su cui non torneremo in maggior dettaglio nel resto di
+questa sezione:
+\begin{itemize*}
+\item Il campo \var{st\_nlink} contiene il numero di \textit{hard link} che
+ fanno riferimento al file (il cosiddetto \textit{link count}) di cui abbiamo
+ già parlato in numerose occasioni.
+\item Il campo \var{st\_ino} contiene il numero di \textit{inode} del file,
+ quello viene usato all'interno del filesystem per identificarlo e che può
+ essere usato da un programma per determinare se due \textit{pathname} fanno
+ riferimento allo stesso file.
+\item Il campo \var{st\_dev} contiene il numero del dispositivo su cui risiede
+ il file (o meglio il suo filesystem). Si tratta dello stesso numero che si
+ usa con \func{mknod} e che può essere decomposto in \textit{major number} e
+ \textit{minor number} con le macro \macro{major} e \macro{minor} viste in
+ sez.~\ref{sec:file_mknod}.
+\item Il campo \var{st\_rdev} contiene il numero di dispositivo associato al
+ file stesso ed ovviamente ha un valore significativo soltanto quando il file
+ è un dispositivo a caratteri o a blocchi.
+\item Il campo \var{st\_blksize} contiene la dimensione dei blocchi di dati
+ usati nell'I/O su disco, che è anche la dimensione usata per la
+ bufferizzazione dei dati dalle librerie del C per l'interfaccia degli
+ \textit{stream}. Leggere o scrivere blocchi di dati in dimensioni inferiori
+ a questo valore è inefficiente in quanto le operazioni su disco usano
+ comunque trasferimenti di questa dimensione.
+\end{itemize*}
+
+Nell'evoluzione del kernel la \textit{system call} che fornisce \func{stat} è
+stata modificata più volte per tener conto dei cambiamenti fatti alla
+struttura \struct{stat},\footnote{questo ha significato l'utilizzo a basso
+ livello di diverse \textit{system call} e diverse versioni della struttura.}
+in particolare a riguardo ai tempi dei file, di cui è stata aumentata la
+precisione (torneremo su questo in sez.~\ref{sec:file_file_times}) ma anche
+per gli aggiornamenti fatti ai campi \var{st\_ino}, \var{st\_uid} e
+\var{st\_gid}.
+
+Sulle piattaforme a 32 bit questi cambiamenti, che han visto un aumento delle
+dimensioni dei campi della struttura per adattarli alle nuove esigenze, sono
+mascherati dalla \acr{glibc} che attraverso \func{stat} invoca la versione più
+recente della \textit{system call} e rimpacchetta i dati se questo è
+necessario per eseguire dei vecchi programmi. Nelle piattaforme a 64 bit
+invece è presente un'unica versione della \textit{system call} e la struttura
+\struct{stat} ha campi di dimensione sufficiente.
+
+Infine a partire dal kernel 2.6.16 è stata introdotta una ulteriore funzione
+della famiglia, \func{fstatat} che consente di trattare con sicurezza i
+\textit{pathname} relativi, la tratteremo in sez.~\ref{sec:file_openat},
+insieme alla nuova \textit{system call} \func{statx}, introdotta dal kernel
+4.11 per estendere l'interfaccia di \func{stat} e le informazioni che essa può
+restituire.
+
+
+\subsection{I tipi di file}
+\label{sec:file_types}
+
+Abbiamo sottolineato fin dall'introduzione che Linux, come ogni sistema
+unix-like, supporta oltre ai file ordinari e alle directory una serie di altri
+``\textsl{tipi}'' di file che possono stare su un filesystem (elencati in
+tab.~\ref{tab:file_file_types}). Il tipo di file viene ritornato dalle
+funzioni della famiglia \func{stat} all'interno del campo \var{st\_mode} di
+una struttura \struct{stat}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Macro} & \textbf{Tipo del file} \\
+ \hline
+ \hline
+ \macrod{S\_ISREG}\texttt{(m)} & File normale.\\
+ \macrod{S\_ISDIR}\texttt{(m)} & Directory.\\
+ \macrod{S\_ISCHR}\texttt{(m)} & Dispositivo a caratteri.\\
+ \macrod{S\_ISBLK}\texttt{(m)} & Dispositivo a blocchi.\\
+ \macrod{S\_ISFIFO}\texttt{(m)} & \textit{Fifo}.\\
+ \macrod{S\_ISLNK}\texttt{(m)} & Collegamento simbolico.\\
+ \macrod{S\_ISSOCK}\texttt{(m)} & Socket.\\
+ \hline
+ \end{tabular}
+ \caption{Macro per i tipi di file (definite in \headfile{sys/stat.h}).}
+ \label{tab:file_type_macro}
+\end{table}
+
+Il campo \var{st\_mode} è una maschera binaria in cui l'informazione viene
+suddivisa nei vari bit che compongono, ed oltre a quelle sul tipo di file,
+contiene anche le informazioni relative ai permessi su cui torneremo in
+sez.~\ref{sec:file_perm_overview}. Dato che i valori numerici usati per
+definire il tipo di file possono variare a seconda delle implementazioni, lo
+standard POSIX definisce un insieme di macro che consentono di verificare il
+tipo di file in maniera standardizzata.
+
+Queste macro vengono usate anche da Linux che supporta pure le estensioni allo
+standard per i collegamenti simbolici e i socket definite da BSD.\footnote{le
+ ultime due macro di tab.~\ref{tab:file_type_macro}, che non sono presenti
+ nello standard POSIX fino alla revisione POSIX.1-1996.} L'elenco completo
+delle macro con cui è possibile estrarre da \var{st\_mode} l'informazione
+relativa al tipo di file è riportato in tab.~\ref{tab:file_type_macro}, tutte
+le macro restituiscono un valore intero da usare come valore logico e prendono
+come argomento il valore di \var{st\_mode}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|l|}
+ \hline
+ \textbf{Flag} & \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{S\_IFMT} & 0170000 & Maschera per i bit del tipo di file.\\
+ \constd{S\_IFSOCK} & 0140000 & Socket.\\
+ \constd{S\_IFLNK} & 0120000 & Collegamento simbolico.\\
+ \constd{S\_IFREG} & 0100000 & File regolare.\\
+ \constd{S\_IFBLK} & 0060000 & Dispositivo a blocchi.\\
+ \constd{S\_IFDIR} & 0040000 & Directory.\\
+ \constd{S\_IFCHR} & 0020000 & Dispositivo a caratteri.\\
+ \constd{S\_IFIFO} & 0010000 & \textit{Fifo}.\\
+ \hline
+ \constd{S\_ISUID} & 0004000 & Set user ID (\acr{suid}) bit, vedi
+ sez.~\ref{sec:file_special_perm}).\\
+ \constd{S\_ISGID} & 0002000 & Set group ID (\acr{sgid}) bit, vedi
+ sez.~\ref{sec:file_special_perm}).\\
+ \constd{S\_ISVTX} & 0001000 & \acr{Sticky} bit, vedi
+ sez.~\ref{sec:file_special_perm}).\\
+ \hline
+ \constd{S\_IRWXU} & 00700 & Maschera per i permessi del proprietario.\\
+ \constd{S\_IRUSR} & 00400 & Il proprietario ha permesso di lettura.\\
+ \constd{S\_IWUSR} & 00200 & Il proprietario ha permesso di scrittura.\\
+ \constd{S\_IXUSR} & 00100 & Il proprietario ha permesso di esecuzione.\\
+ \hline
+ \constd{S\_IRWXG} & 00070 & Maschera per i permessi del gruppo.\\
+ \constd{S\_IRGRP} & 00040 & Il gruppo ha permesso di lettura.\\
+ \constd{S\_IWGRP} & 00020 & Il gruppo ha permesso di scrittura.\\
+ \constd{S\_IXGRP} & 00010 & Il gruppo ha permesso di esecuzione.\\
+ \hline
+ \constd{S\_IRWXO} & 00007 & Maschera per i permessi di tutti gli altri\\
+ \constd{S\_IROTH} & 00004 & Gli altri hanno permesso di lettura.\\
+ \constd{S\_IWOTH} & 00002 & Gli altri hanno permesso di esecuzione.\\
+ \constd{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 \headfile{sys/stat.h}).}
+ \label{tab:file_mode_flags}
+\end{table}
+
+Oltre alle macro di tab.~\ref{tab:file_type_macro}, che semplificano
+l'operazione, è 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 \headfile{sys/stat.h} sono definite le varie
+costanti numeriche riportate in tab.~\ref{tab:file_mode_flags}, che
+definiscono le maschere che consentono di selezionare non solo i dati relativi
+al tipo di file, ma anche le informazioni relative ai permessi su cui
+torneremo in sez.~\ref{sec:file_access_control}, ed identificare i rispettivi
+valori.
+
+Le costanti che servono per la identificazione del tipo di file sono riportate
+nella prima sezione di tab.~\ref{tab:file_mode_flags}, mentre le sezioni
+successive attengono alle costanti usate per i permessi. Il primo valore
+dell'elenco è la maschera binaria \const{S\_IFMT} che permette di estrarre da
+\var{st\_mode} (con un AND aritmetico) il blocco di bit nei quali viene
+memorizzato il tipo di file. I valori successivi sono le costanti
+corrispondenti ai vari tipi di file, e possono essere usate per verificare la
+presenza del tipo di file voluto ed anche, con opportune combinazioni,
+alternative fra più tipi di file.
+
+Si tenga presente però che a differenza dei permessi, l'informazione relativa
+al tipo di file non è una maschera binaria, per questo motivo se si volesse
+impostare una condizione che permetta di controllare se un file è una
+directory o un file ordinario non si possono controllare dei singoli bit, ma
+si dovrebbe usare una macro di preprocessore come:
+\includecodesnip{listati/is_regdir.h}
+in cui si estraggono ogni volta da \var{st\_mode} i bit relativi al tipo di
+file e poi si effettua il confronto con i due possibili tipi di file.
+
+
+\subsection{Le dimensioni dei file}
+\label{sec:file_file_size}
+
+Abbiamo visto in fig.~\ref{fig:file_stat_struct} che campo \var{st\_size} di
+una struttura \struct{stat} contiene la dimensione del file in byte. In realtà
+questo è vero solo se si tratta di un file regolare contenente dei dati; nel
+caso di un collegamento simbolico invece la dimensione è quella del
+\textit{pathname} che il collegamento stesso contiene, e per una directory
+quella dello spazio occupato per le voci della stessa (che dipende da come
+queste vengono mantenute dal filesystem), infine per le \textit{fifo}, i socket
+ed i file di dispositivo questo campo è sempre nullo.
+
+Il campo \var{st\_blocks} invece definisce la lunghezza del file espressa in
+numero di blocchi di 512 byte. La differenza con \var{st\_size} è che in
+questo caso si fa riferimento alla quantità di spazio disco allocata per il
+file, e non alla dimensione dello stesso che si otterrebbe leggendolo
+sequenzialmente.
+
+Si deve tener presente infatti che la lunghezza del file riportata in
+\var{st\_size} non è detto che corrisponda all'occupazione dello spazio su
+disco, e non solo perché la parte finale del file potrebbe riempire
+parzialmente un blocco. In un sistema unix-like infatti è possibile
+l'esistenza dei cosiddetti \textit{sparse file}, cioè file in cui sono
+presenti dei ``\textsl{buchi}'' (\textit{holes} nella nomenclatura inglese)
+che si formano tutte le volte che si va a scrivere su un 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 il contenuto del file (ad esempio usando il comando \cmd{wc -c}), dato
+che in tal caso per i ``\textsl{buchi}'' vengono restituiti degli zeri, si
+avrà lo stesso risultato di \cmd{ls}.
+
+Se è sempre possibile allargare un file, scrivendoci sopra o usando la
+funzione \func{lseek} (vedi sez.~\ref{sec:file_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} (vedi sez.~\ref{sec:file_open_close}), ma questo è un caso
+particolare; per qualunque altra dimensione si possono usare le due funzioni
+di sistema \funcd{truncate} e \funcd{ftruncate}, i cui prototipi sono:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int ftruncate(int fd, off\_t length))}
+\fdecl{int truncate(const char *file\_name, off\_t length)}
+\fdesc{Troncano un file.}
+}
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINTR}] si è stati interrotti da un segnale.
+ \item[\errcode{EINVAL}] \param{length} è negativa o maggiore delle
+ dimensioni massime di un file.
+ \item[\errcode{EPERM}] il filesystem non supporta il troncamento di un file.
+ \item[\errcode{ETXTBSY}] il file è un programma in esecuzione.
+ \end{errlist}
+ per entrambe, mentre per \func{ftruncate} si avranno anche:
+ \begin{errlist}
+ \item[\errcode{EBADF}] \param{fd} non è un file descriptor.
+ \item[\errcode{EINVAL}] \param{fd} non è un riferimento a un file o non è
+ aperto in scrittura.
+ \end{errlist}
+ e per \func{truncate} si avranno anche:
+ \begin{errlist}
+ \item[\errcode{EACCES}] non si ha il permesso di scrittura sul file o il
+ permesso di attraversamento di una delle componenti del \textit{pathname}.
+ \item[\errcode{EISDIR}] \param{file\_name} fa riferimento ad una directory.
+ \end{errlist}
+ ed inoltre \errval{EFAULT}, \errval{EIO}, \errval{ELOOP},
+ \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR} e \errval{EROFS}
+ nel loro significato generico.}
+\end{funcproto}
+
+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 un \textit{pathname} per \func{truncate}
+e con un file descriptor per \funcd{ftruncate}. Si tenga presente che se il
+file è più lungo della lunghezza specificata i dati in eccesso saranno
+perduti.
+
+Il comportamento in caso di lunghezza del file inferiore a \param{length} 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 \textsl{buco} nel 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, che sono registrati
+nell'\textit{inode} insieme agli altri attributi del file. Questi possono
+essere letti tramite la funzione \func{stat}, che li restituisce attraverso
+tre campi della struttura \struct{stat} di fig.~\ref{fig:file_stat_struct}. Il
+significato di questi tempi e dei relativi campi della struttura \struct{stat}
+è illustrato nello schema di tab.~\ref{tab:file_file_times}, dove è anche
+riportato un esempio delle funzioni che effettuano cambiamenti su di essi. Il
+valore del tempo è espresso nel cosiddetto \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}) riportato in \var{st\_mtime},
+ed il tempo di ultimo cambiamento di stato (il \textit{change status time})
+riportato in \var{st\_ctime}. Il primo infatti fa riferimento ad una modifica
+del contenuto di un file, mentre il secondo ad una modifica dei metadati
+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 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 perché
+più recenti dei loro sorgenti oppure dai programmi di backup, talvolta insieme
+anche al tempo di cambiamento di stato, per decidere quali file devono essere
+aggiornati nell'archiviazione. 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 mai conto dell'ultimo accesso 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}. Si noti anche come in
+tab.~\ref{tab:file_file_times} non venga riportato il \textsl{tempo di
+ creazione} di un file; in un sistema unix-like infatti questo non esiste, e
+non è previsto dall'interfaccia classica, ma essendo usato da altri sistemi
+operativi (in particolare Windows) in tutti i filesystem più recenti ne viene
+supportata la registrazione, ed a partire dal kernel 4.11 è diventato
+possibile anche ottenerne la lettura con la nuova \textit{system call}
+\func{statx} (che tratteremo in sez.~\ref{sec:file_openat}).
+
+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 i cicli di riscrittura per i dischi su memorie riscrivibili.
+
+Per questo motivo abbiamo visto in sez.~\ref{sec:filesystem_mounting} come nel
+corso dello sviluppo del kernel siano stati introdotti degli opportuni
+\textit{mount flag} che consentono di evitare di aggiornare continuamente una
+informazione che nella maggior parte dei casi non ha un interesse
+rilevante. Per questo motivo i valori dell'\textit{access time} possono
+dipendere dalle opzioni di montaggio, ed anche, essendo stato cambiato il
+comportamento di default a partire dalla versione 2.6.30, dal kernel che si
+sta usando.
+
+In generale quello che avviene con i kernel più recenti è che il tempo di
+ultimo accesso viene aggiornato solo se è precedente al tempo di ultima
+modifica o cambiamento, o se è cambiato ed passato più di un giorno
+dall'ultimo aggiornamento. Così si può rendere evidente che vi è stato un
+accesso dopo una modifica, e che il file viene comunque osservato a cadenza
+regolare, conservando le informazioni veramente utili senza consumare
+inutilmente risorse in continue scritture per mantenere costantemente
+aggiornata una informazione che a questo punto non ha più nessuna rilevanza
+pratica.\footnote{qualora ce ne fosse la necessità è comunque possibile,
+ tramite l'opzione di montaggio \texttt{strictatime}, richiedere in ogni caso
+ il comportamento tradizionale.}
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|c|c|c|c|c|c|l|}
+ \hline
+ \multicolumn{1}{|p{2.3cm}|}{\centering{\vspace{6pt}\textbf{Funzione}}} &
+ \multicolumn{3}{|p{3.2cm}|}{\centering{
+ \textbf{File o directory del riferimento}}}&
+ \multicolumn{3}{|p{3.2cm}|}{\centering{
+ \textbf{Directory contenente il riferimento}}}
+ &\multicolumn{1}{|p{3.cm}|}{\centering{\vspace{6pt}\textbf{Note}}} \\
+ \cline{2-7}
+ \cline{2-7}
+ \multicolumn{1}{|p{2.3cm}|}{}
+ &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(a)}}}
+ &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(m)}}}
+ &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(c)}}}
+ &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(a)}}}
+ &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(m)}}}
+ &\multicolumn{1}{|p{.8cm}|}{\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{mknod}
+ &$\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 ambo gli argomenti\\
+ \func{rmdir}
+ & -- & -- & -- & -- &$\bullet$&$\bullet$&\\
+ \func{truncate}
+ & -- &$\bullet$&$\bullet$& -- & -- & -- &\\
+ \func{ftruncate}
+ & -- &$\bullet$&$\bullet$& -- & -- & -- &\\
+ \func{unlink}
+ & -- & -- &$\bullet$& -- &$\bullet$&$\bullet$&\\
+ \func{utime}
+ &$\bullet$&$\bullet$&$\bullet$& -- & -- & -- &\\
+ \func{utimes}
+ &$\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 di
+ stato \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 immediatamente se si tiene
+conto di quanto già detto e ripetuto a partire da
+sez.~\ref{sec:file_filesystem}, 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 ultima
+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 ricordi infine come \var{st\_ctime} non è il tempo di creazione del file,
+che in Unix non esiste, anche se può corrispondervi per file che non sono mai
+stati modificati. Per questo motivo, a differenza di quanto avviene con altri
+sistemi operativi, 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 in cui si è effettuata la copia come data di
+ultima modifica.
+
+I tempi di ultimo accesso ed ultima modifica possono essere modificati
+esplicitamente usando la funzione di sistema \funcd{utime}, il cui prototipo
+è:
+
+\begin{funcproto}{
+\fhead{utime.h}
+\fdecl{int utime(const char *filename, struct utimbuf *times)}
+\fdesc{Modifica i tempi di ultimo accesso ed ultima modifica di un file.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] non c'è il permesso di attraversamento per uno dei
+ componenti di \param{filename} o \param{times} è \val{NULL} e non si ha il
+ permesso di scrittura sul file, o non si è proprietari del file o non si
+ hanno i privilegi di amministratore.
+ \item[\errcode{EPERM}] \param{times} non è \val{NULL}, e non si è
+ proprietari del file o non si hanno i privilegi di amministratore.
+ \end{errlist}
+ ed inoltre \errval{ENOENT} e \errval{EROFS} nel loro significato generico.}
+\end{funcproto}
+
+La funzione cambia i tempi di ultimo accesso e di ultima 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]{0.8\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 ed i privilegi necessari per eseguirla dipendono dal
+valore dell'argomento \param{times}. Se è \val{NULL} la funzione imposta il
+tempo corrente ed è sufficiente avere accesso in scrittura al file o essere
+proprietari del file o avere i privilegi di amministratore. Se invece si è
+specificato un valore diverso la funzione avrà successo solo se si è
+proprietari del file o se si hanno i privilegi di amministratore.\footnote{per
+ essere precisi la capacità \const{CAP\_FOWNER}, vedi
+ sez.~\ref{sec:proc_capabilities}.} In entrambi i casi per verificare la
+proprietà del file viene utilizzato l'\ids{UID} effettivo del processo.
+
+Si tenga presente che non è possibile modificare manualmente il tempo di
+cambiamento di stato del file, che viene aggiornato direttamente dal kernel
+tutte le volte che si modifica l'\textit{inode}, e 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 file di
+dispositivo, scrivendo direttamente sul disco senza passare attraverso il
+filesystem, ma ovviamente in questo modo la cosa è più complicata da
+realizzare.\footnote{esistono comunque molti programmi che consentono di farlo
+ con relativa semplicità per cui non si dia per scontato che il valore sia
+ credibile in caso di macchina compromessa.}
+
+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. L'ulteriore informazione può
+essere ottenuta 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 sistema, \funcd{utimes}, che consente di specificare tempi con maggior
+precisione; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/time.h}
+\fdecl{int utimes(const char *filename, struct timeval times[2])}
+\fdesc{Modifica i tempi di ultimo accesso e ultima modifica di un file.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà gli stessi valori di \func{utime}.}
+\end{funcproto}
+
+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]{0.8\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 per la
+% manipolazione dei tempi dei file,\footnote{le due funzioni non sono definite
+% in nessuno standard, ma sono presenti, oltre che su Linux, anche su BSD;
+% sono accessibili definendo \macro{\_DEFAULT\_SOURCE} dalla \acr{glibc} 2.19
+% o \macro{\_GNU\_SOURCE} prima.} la prima è \funcd{futimes} e consente di
+% effettuare la modifica utilizzando un file già aperto, il suo prototipo è:
+
+% \begin{funcproto}{
+% \fhead{sys/time.h}
+% \fdecl{int futimes(int fd, const struct timeval tv[2])}
+% \fdesc{Cambia i tempi di un file già aperto.}
+% }
+
+% {La funzione ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+% caso \var{errno} assumerà uno gli stessi valori di \func{utimes} ed inoltre:
+% \begin{errlist}
+% \item[\errcode{EBADF}] \param{fd} non è un file descriptor.
+% \item[\errcode{ENOSYS}] il filesystem \texttt{/proc} non è accessibile.
+% \end{errlist}}
+% \end{funcproto}
+
+% La seconda funzione, introdotta a partire dal kernel 2.6.22, è
+% \funcd{lutimes}, e consente rispettivamente di modificare i tempi di un
+% collegamento simbolico; il suo prototipo è:
+
+% \begin{funcproto}{
+% \fhead{sys/time.h}
+% \fdecl{int lutimes(const char *filename, const struct timeval tv[2])}
+% \fdesc{Cambia i tempi di un collegamento simbolico.}
+% }
+
+% {La funzione ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+% caso \var{errno} assumerà uno gli stessi valori di \func{utimes}, con in più:
+% \begin{errlist}
+% \item[\errcode{ENOSYS}] la funzione non è supportata.
+% \end{errlist}}
+% \end{funcproto}
+
+% Le due funzioni hanno 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 se questo è già aperto facendo
+% riferimento al suo file descriptor, mentre con \func{lutimes}, nel caso in cui
+% \param{filename} sia un collegamento simbolico, saranno modificati i suoi
+% tempi invece di quelli del file a cui esso punta.
+
+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; sono accessibili definendo
+ \macro{\_DEFAULT\_SOURCE} dalla \acr{glibc} 2.19 o \macro{\_GNU\_SOURCE}
+ prima.} \funcd{futimes} e \funcd{lutimes}, che consentono rispettivamente
+di effettuare la modifica utilizzando un file già aperto o di eseguirla
+direttamente su un collegamento simbolico. I relativi prototipi sono:
+
+\begin{funcproto}{
+\fhead{sys/time.h}
+\fdecl{int futimes(int fd, const struct timeval tv[2])}
+\fdesc{Cambia i tempi di un file già aperto.}
+\fdecl{int lutimes(const char *filename, const struct timeval tv[2])}
+\fdesc{Cambia i tempi di un collegamento simbolico.}
+}
+
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno 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 per
+ \func{futimes} o la funzione non è supportata per \func{lutimes}.
+ \end{errlist}}
+\end{funcproto}
+
+Le due funzioni hanno 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 se questo è già aperto facendo
+riferimento al suo file descriptor, mentre con \func{lutimes} nel caso in
+cui \param{filename} sia un collegamento simbolico saranno modificati i suoi
+tempi invece di quelli del file a cui esso punta.
+
+Nonostante il kernel nelle versioni più recenti supporti, come accennato,
+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 di sistema, \func{utimensat} (che
+vedremo in sez.~\ref{sec:file_openat} insieme alle altre
+\textit{at-functions}), e \funcd{futimens}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/time.h}
+\fdecl{int futimens(int fd, const struct timespec times[2])}
+\fdesc{Cambia i tempi di un file già aperto.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] si è richiesta l'impostazione del tempo corrente ma
+ non si ha il permesso di scrittura sul file, o non si è proprietari del
+ file o non si hanno i privilegi di amministratore; oppure il file è
+ immutabile (vedi sez.~\ref{sec:file_perm_overview}).
+ \item[\errcode{EBADF}] \param{fd} non è un file descriptor valido.
+ \item[\errcode{EFAULT}] \param{times} non è un puntatore valido.
+ \item[\errcode{EINVAL}] si sono usati dei valori non corretti per i tempi di
+ \param{times}.
+ \item[\errcode{EPERM}] si è richiesto un cambiamento nei tempi non al tempo
+ corrente, ma non si è proprietari del file o non si hanno i privilegi di
+ amministratore; oppure il file è immutabile o \textit{append-only} (vedi
+ sez.~\ref{sec:file_perm_overview}).
+ \end{errlist}
+ ed inoltre per entrambe \errval{EROFS} nel suo significato generico.}
+\end{funcproto}
+
+La funzione è sostanzialmente una estensione di \func{futimes} che consente di
+specificare i tempi con precisione maggiore. Per questo per indicare i valori
+dei tempi da impostare utilizza un vettore \param{times} di due strutture
+\struct{timespec} che permettono di indicare il valore del tempo con una
+precisione fino al nanosecondo (se ne è riportata la definizione in
+fig.~\ref{fig:sys_timespec_struct}).
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.8\textwidth}
+ \includestruct{listati/timespec.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{timespec} usata per indicare valori di tempo
+ con la precisione del nanosecondo.}
+ \label{fig:sys_timespec_struct}
+\end{figure}
+
+Come per le precedenti funzioni il primo elemento di \param{times} indica il
+tempo di ultimo accesso ed il secondo quello di ultima modifica, e se si usa
+il valore \val{NULL} verrà impostato il tempo corrente sia per l'ultimo
+accesso che per l'ultima modifica.
+
+Nei singoli elementi di \param{times} si possono inoltre utilizzare due valori
+speciali per il campo \var{tv\_nsec}: con \constd{UTIME\_NOW} si richiede
+l'uso del tempo corrente, mentre con \constd{UTIME\_OMIT} si richiede di non
+impostare il tempo. Si può così aggiornare in maniera specifica soltanto uno
+fra il tempo di ultimo accesso e quello di ultima modifica. Quando si usa uno
+di questi valori speciali per \var{tv\_nsec} il corrispondente valore di
+\var{tv\_sec} viene ignorato.
+
+Questa funzione e \func{utimensat} sono una estensione definita nella
+revisione POSIX.1-2008 dello standard POSIX; in Linux sono state introdotte a
+partire dal kernel 2.6.22, e sono supportate dalla \acr{glibc} a partire dalla
+versione 2.6, si tenga presente però che per kernel precedenti il 2.6.26 le
+due funzioni sono difettose nel rispetto di alcuni requisiti minori dello
+standard e nel controllo della correttezza dei tempi, per i dettagli dei quali
+si rimanda alla pagina di manuale.
+
+
+\section{Il controllo di accesso ai file}
+\label{sec:file_access_control}
+
+Una delle caratteristiche fondamentali di tutti i sistemi unix-like è quella
+del controllo di accesso ai file, che viene implementato per qualunque
+filesystem standard.\footnote{per filesystem standard si intende un filesystem
+ che implementi le caratteristiche previste dallo standard POSIX; in Linux
+ sono utilizzabili anche filesystem di altri sistemi operativi, che non
+ supportano queste caratteristiche.} In questa sezione ne esamineremo i
+concetti essenziali e le funzioni usate per gestirne i vari aspetti.
+
+
+\subsection{I permessi per l'accesso ai file}
+\label{sec:file_perm_overview}
+
+Ad ogni file Linux associa sempre, oltre ad un insieme di permessi, l'utente
+che ne è proprietario (il cosiddetto \textit{owner}) ed un gruppo di
+appartenenza, indicati dagli identificatori di utente e gruppo (\ids{UID} e
+\ids{GID}) di cui abbiamo già parlato in
+sez.~\ref{sec:proc_access_id}.\footnote{questo è vero solo per filesystem di
+ tipo Unix, ad esempio non è vero per il filesystem VFAT di Windows, che non
+ fornisce nessun supporto per l'accesso multiutente, e per il quale queste
+ proprietà vengono assegnate in maniera fissa con opportune opzioni di
+ montaggio.} Anche questi sono mantenuti sull'\textit{inode} insieme alle
+altre proprietà e sono accessibili da programma tramite la funzione
+\func{stat} (trattata in sez.~\ref{sec:file_stat}), che restituisce l'utente
+proprietario nel campo \var{st\_uid} ed il gruppo proprietario nel campo
+\var{st\_gid} della omonima struttura \struct{stat}.
+
+Il controllo di accesso ai file segue un modello abbastanza semplice che
+prevede tre permessi fondamentali strutturati su tre livelli di accesso.
+Esistono varie estensioni a questo modello,\footnote{come le \textit{Access
+ Control List} che sono state aggiunte ai filesystem standard con opportune
+ estensioni (vedi sez.~\ref{sec:file_ACL}) per arrivare a meccanismi di
+ controllo ancora più sofisticati come il \textit{Mandatory Access Control}
+ di \textit{SELinux} e delle altre estensioni come \textit{Smack} o
+ \textit{AppArmor}.} ma nella maggior parte dei casi il meccanismo standard è
+più che sufficiente a soddisfare tutte le necessità più comuni. I tre
+permessi di base associati ad ogni file sono:
+\begin{itemize*}
+\item il permesso di lettura (indicato con la lettera \texttt{r}, dall'inglese
+ \textit{read}).
+\item il permesso di scrittura (indicato con la lettera \texttt{w},
+ dall'inglese \textit{write}).
+\item il permesso di esecuzione (indicato con la lettera \texttt{x},
+ dall'inglese \textit{execute}).
+\end{itemize*}
+mentre i tre livelli su cui sono divisi i privilegi sono:
+\begin{itemize*}
+\item i privilegi per l'utente proprietario del file.
+\item i privilegi per un qualunque utente faccia parte del gruppo cui
+ appartiene il file.
+\item i privilegi per tutti gli altri utenti.
+\end{itemize*}
+
+L'insieme dei permessi viene espresso con un numero a 12 bit; di questi i nove
+meno significativi sono usati a gruppi di tre per indicare i permessi base di
+lettura, scrittura ed esecuzione e sono applicati rispettivamente
+rispettivamente al proprietario, al gruppo, a tutti gli altri.
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=8cm]{img/fileperm}
+ \caption{Lo schema dei bit utilizzati per specificare i permessi di un file
+ contenuti nel campo \var{st\_mode} di \struct{stat}.}
+ \label{fig:file_perm_bit}
+\end{figure}
+
+I restanti tre bit (noti come \textit{suid bit}, \textit{sgid bit}, e
+\textit{sticky bit}) sono usati per indicare alcune caratteristiche più
+complesse del meccanismo del controllo di accesso su cui torneremo in seguito
+(in sez.~\ref{sec:file_special_perm}), lo schema di allocazione dei bit è
+riportato in fig.~\ref{fig:file_perm_bit}. Come tutte le altre proprietà di
+un file anche i permessi sono memorizzati nell'\textit{inode}, e come
+accennato in sez.~\ref{sec:file_types} essi vengono restituiti in una parte
+del campo \var{st\_mode} della struttura \struct{stat} (si veda di nuovo
+fig.~\ref{fig:file_stat_struct}).
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|c|l|}
+ \hline
+ \textbf{\var{st\_mode}} bit & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{S\_IRUSR} & \textit{user-read}, l'utente può leggere.\\
+ \const{S\_IWUSR} & \textit{user-write}, l'utente può scrivere.\\
+ \const{S\_IXUSR} & \textit{user-execute}, l'utente può eseguire.\\
+ \hline
+ \const{S\_IRGRP} & \textit{group-read}, il gruppo può leggere.\\
+ \const{S\_IWGRP} & \textit{group-write}, il gruppo può scrivere.\\
+ \const{S\_IXGRP} & \textit{group-execute}, il gruppo può eseguire.\\
+ \hline
+ \const{S\_IROTH} & \textit{other-read}, tutti possono leggere.\\
+ \const{S\_IWOTH} & \textit{other-write}, tutti possono scrivere.\\
+ \const{S\_IXOTH} & \textit{other-execute}, tutti possono eseguire.\\
+ \hline
+ \end{tabular}
+ \caption{I bit dei permessi di accesso ai file, come definiti in
+ \texttt{<sys/stat.h>}}
+ \label{tab:file_bit_perm}
+\end{table}
+
+
+In genere ci si riferisce ai tre livelli dei privilegi usando le lettere
+\texttt{u} (per \textit{user}), \texttt{g} (per \textit{group}) e \texttt{o}
+(per \textit{other}), inoltre se si vuole indicare tutti i raggruppamenti
+insieme si usa la lettera \texttt{a} (per \textit{all}). Si tenga ben presente
+questa distinzione dato che in certi casi, mutuando la terminologia in uso a
+suo tempo nel VMS, si parla dei permessi base come di permessi per
+\textit{owner}, \textit{group} ed \textit{all}, le cui iniziali possono dar
+luogo a confusione. Le costanti che permettono di accedere al valore numerico
+di questi bit nel campo \var{st\_mode}, già viste in
+tab.~\ref{tab:file_mode_flags}, sono riportate per chiarezza una seconda volta
+in tab.~\ref{tab:file_bit_perm}.
+
+I permessi vengono usati in maniera diversa dalle varie funzioni, e a seconda
+che si riferiscano a dei file, dei collegamenti simbolici o delle directory;
+qui ci limiteremo ad un riassunto delle regole generali, entrando nei dettagli
+più avanti.
+
+La prima regola è che per poter accedere ad un file attraverso il suo
+\textit{pathname} occorre il permesso di esecuzione in ciascuna delle
+directory che compongono il \textit{pathname}; lo stesso vale per aprire un
+file nella directory corrente (per la quale appunto serve il diritto di
+esecuzione). Per una directory infatti il permesso di esecuzione significa che
+essa può essere attraversata nella risoluzione del \textit{pathname}, e per
+questo viene anche chiamato permesso di attraversamento. Esso è sempre
+distinto dal permesso di lettura che invece implica che si può leggere il
+contenuto della directory.
+
+Questo significa che se si ha il permesso di esecuzione senza permesso di
+lettura si potrà lo stesso aprire un file all'interno di una directory (se si
+hanno i permessi adeguati per il medesimo) ma non si potrà vederlo con
+\cmd{ls} mancando il permesso di leggere il contenuto della directory. Per
+crearlo o rinominarlo o cancellarlo invece occorrerà avere anche il permesso
+di scrittura per la directory.
+
+Avere il permesso di lettura per un file consente di aprirlo con le opzioni
+(si veda quanto riportato in sez.~\ref{sec:file_open_close}) di sola lettura o
+di lettura/scrittura e leggerne il contenuto. Avere il permesso di scrittura
+consente di aprire un file in sola scrittura o lettura/scrittura e modificarne
+il contenuto, lo stesso permesso è necessario per poter troncare il file o per
+aggiornare il suo tempo di ultima modifica al tempo corrente, ma non per
+modificare arbitrariamente quest'ultimo, operazione per la quale, come per
+buona parte delle modifiche effettuate sui metadati del file, occorre esserne
+i proprietari.
+
+Non si può creare un file fintanto che non si disponga del permesso di
+esecuzione e di quello di scrittura per la directory di destinazione. Gli
+stessi permessi occorrono per cancellare un file da una directory (si ricordi
+che questo non implica necessariamente la rimozione del contenuto del file dal
+disco).
+
+Per la cancellazione non è necessario nessun tipo di permesso per il file
+stesso dato che, come illustrato in sez.~\ref{sec:link_symlink_rename} esso
+non viene toccato, nella cancellazione infatti viene solo modificato il
+contenuto della directory, rimuovendo la voce che ad esso fa riferimento. Lo
+stesso vale per poter rinominare o spostare il file in altra directory, in
+entrambi i casi occorrerà il permesso di scrittura sulle directory che si
+vanno a modificare.
+
+Per poter eseguire un file, che sia un programma compilato od uno script di
+shell, od un altro tipo di file eseguibile riconosciuto dal kernel, occorre
+oltre al permesso di lettura per accedere al contenuto avere anche il permesso
+di esecuzione. Inoltre solo i file regolari possono essere eseguiti. Per i
+file di dispositivo i permessi validi sono solo quelli di lettura e scrittura,
+che corrispondono al poter eseguire dette operazioni sulla periferica
+sottostante.
+
+I permessi per un collegamento simbolico sono ignorati, contano quelli del
+file a cui fa riferimento; per questo in genere il comando \cmd{ls} riporta
+per un collegamento simbolico tutti i permessi come concessi. Utente e gruppo
+a cui esso appartiene vengono pure ignorati quando il collegamento viene
+risolto, vengono controllati solo quando viene richiesta la rimozione del
+collegamento e quest'ultimo è in una directory con lo \textit{sticky bit}
+impostato (si veda sez.~\ref{sec:file_special_perm}).
+
+La procedura con cui il kernel stabilisce se un processo possiede un certo
+permesso (di lettura, scrittura o esecuzione) si basa sul confronto fra
+l'utente e il gruppo a cui il file appartiene (i valori di \var{st\_uid} e
+\var{st\_gid} accennati in precedenza) e l'\ids{UID} effettivo, il \ids{GID}
+effettivo e gli eventuali \ids{GID} supplementari del processo.\footnote{in
+ realtà Linux, per quanto riguarda l'accesso ai file, utilizza gli
+ identificatori del gruppo \textit{filesystem} (si ricordi quanto esposto in
+ sez.~\ref{sec:proc_perms}), ma essendo questi del tutto equivalenti ai primi,
+ eccetto il caso in cui si voglia scrivere un server NFS, ignoreremo questa
+ differenza.}
+
+Per una spiegazione dettagliata degli identificatori associati ai processi si
+veda sez.~\ref{sec:proc_perms}; normalmente, a parte quanto vedremo in
+sez.~\ref{sec:file_special_perm}, l'\ids{UID} effettivo e il \ids{GID} effettivo
+corrispondono ai valori dell'\ids{UID} e del \ids{GID} dell'utente che ha
+lanciato il processo, mentre i \ids{GID} supplementari sono quelli dei gruppi
+cui l'utente appartiene.
+
+I passi attraverso i quali viene stabilito se il processo possiede il diritto
+di accesso sono i seguenti:
+\begin{enumerate*}
+\item Se l'\ids{UID} effettivo del processo è zero (corrispondente
+ all'amministratore) l'accesso è sempre garantito senza nessun controllo. Per
+ questo motivo l'amministratore ha piena libertà di accesso a tutti i file.
+\item Se l'\ids{UID} effettivo del processo è uguale all'\ids{UID} del
+ proprietario del file (nel qual caso si dice che il processo è proprietario
+ del file) allora:
+ \begin{itemize*}
+ \item se il relativo\footnote{per relativo si intende il bit di
+ \textit{user-read} se il processo vuole accedere in lettura, quello di
+ \textit{user-write} per l'accesso in scrittura, ecc.} bit dei permessi
+ d'accesso dell'utente è impostato, l'accesso è consentito;
+ \item altrimenti l'accesso è negato.
+ \end{itemize*}
+\item Se il \ids{GID} effettivo del processo o uno dei \ids{GID} supplementari
+ del processo corrispondono al \ids{GID} del file allora:
+ \begin{itemize*}
+ \item se il bit dei permessi d'accesso del gruppo è impostato, l'accesso è
+ consentito;
+ \item altrimenti l'accesso è negato.
+ \end{itemize*}
+\item Se il bit dei permessi d'accesso per tutti gli altri è impostato,
+ l'accesso è consentito, altrimenti l'accesso è negato.
+\end{enumerate*}
+
+Si tenga presente che questi passi vengono eseguiti esattamente in
+quest'ordine. Questo vuol dire che se un processo è il proprietario di un
+file, l'accesso è consentito o negato solo sulla base dei permessi per
+l'utente; i permessi per il gruppo non vengono neanche controllati. Lo stesso
+vale se il processo appartiene ad un gruppo appropriato, in questo caso i
+permessi per tutti gli altri non vengono controllati.
+
+Questo significa che se si è proprietari di un file ma non si ha il permesso
+di scrittura, non vi si potrà scrivere anche se questo fosse scrivibile per
+tutti gli altri. Permessi di questo tipo sono ovviamente poco ortodossi, e
+comunque, come vedremo in sez.~\ref{sec:file_perm_management}, il proprietario
+di un file può sempre modificarne i permessi, e riassegnarsi un eventuale
+permesso di scrittura mancante.
+
+\itindbeg{file~attributes}
+
+A questi che sono i permessi ordinari si aggiungono, per i filesystem che
+supportano questa estensione, due permessi speciali mantenuti nei cosiddetti
+\textit{file attributes}, che si possono leggere ed impostare con i comandi
+\cmd{lsattr} e \cmd{chattr}.\footnote{per l'utilizzo di questi comandi e per
+ le spiegazioni riguardo tutti gli altri \textit{file attributes} si rimanda
+ alla sezione 1.4.4 di \cite{AGL}.}
+
+Il primo è il cosiddetto attributo di immutabilità (\textit{immutable},
+identificato dalla lettera \texttt{i}) che impedisce ogni modifica al file,
+\textit{inode} compreso. Questo significa non solo che non se ne può cambiare
+il contenuto, ma neanche nessuna delle sue proprietà, ed in particolare non si
+può modificare nei permessi o nei tempi o nel proprietario ed inoltre, visto
+che non se può modificare il \textit{link count}, non si può neanche
+cancellare, rinominare, o creare \textit{hard link} verso di esso.
+
+Il secondo è il cosiddetto attributo di \textit{append-only}, (identificato
+dalla lettera \texttt{a}) che consente soltanto la scrittura in coda al
+file. Il file cioè può essere soltanto esteso nel contenuto, ma i suoi
+metadati, a parte i tempi che però possono essere impostati al valore
+corrente, non possono essere modificati in alcun modo, quindi di nuovo non si
+potrà cancellare, rinominare, o modificare nei permessi o nelle altre
+proprietà.
+
+Entrambi questi attributi attivano queste restrizioni a livello di filesystem,
+per cui a differenza dei permessi ordinari esse varranno per qualunque utente
+compreso l'amministratore. L'amministratore è l'unico che può attivare o
+disattivare questi attributi,\footnote{più precisamente un processo con la
+ capacità \const{CAP\_LINUX\_IMMUTABLE}, vedi
+ sez.~\ref{sec:proc_capabilities}.} e potendo rimuoverli è comunque capace di
+tornare in grado di eseguire qualunque operazione su un file immutabile o
+\textit{append-only}.
+
+\itindend{file~attributes}
+
+
+
+\subsection{I bit dei permessi speciali}
+\label{sec:file_special_perm}
+
+\itindbeg{suid~bit}
+\itindbeg{sgid~bit}
+
+Come si è accennato (in sez.~\ref{sec:file_perm_overview}) nei dodici bit del
+campo \var{st\_mode} di \struct{stat} che vengono usati per il controllo di
+accesso oltre ai bit dei permessi veri e propri, ci sono altri tre bit che
+vengono usati per indicare alcune proprietà speciali dei file. Due di questi
+sono i bit detti \acr{suid} (da \textit{set-user-ID bit}) e \acr{sgid} (da
+\textit{set-group-ID bit}) che sono identificati dalle costanti
+\const{S\_ISUID} e \const{S\_ISGID}.
+
+Come spiegato in dettaglio in sez.~\ref{sec:proc_exec}, quando si lancia un
+programma il comportamento normale del kernel è quello di impostare gli
+identificatori del gruppo \textit{effective} del nuovo processo al valore dei
+corrispondenti del gruppo \textit{real} del processo corrente, che normalmente
+corrispondono a quelli dell'utente con cui si è entrati nel sistema.
+
+Se però il file del programma, che ovviamente deve essere
+eseguibile,\footnote{anzi più precisamente un binario eseguibile: per motivi
+ di sicurezza il kernel ignora i bit \acr{suid} e \acr{sgid} per gli script
+ eseguibili.} ha il bit \acr{suid} impostato, il kernel assegnerà come
+\ids{UID} effettivo al nuovo processo l'\ids{UID} del proprietario del file al
+posto dell'\ids{UID} del processo originario. Avere il bit \acr{sgid}
+impostato ha lo stesso effetto sul \ids{GID} effettivo del processo. É
+comunque possibile riconoscere questa situazione perché il cambiamento viene
+effettuato solo sugli identificativi del gruppo \textit{effective}, mentre
+quelli dei gruppi \textit{real} e \textit{saved} restano quelli dell'utente
+che ha eseguito il programma.
+
+I bit \acr{suid} e \acr{sgid} vengono usati per permettere agli utenti normali
+di usare programmi che richiedono privilegi speciali. L'esempio classico è il
+comando \cmd{passwd} che ha la necessità di modificare il file delle password,
+quest'ultimo ovviamente può essere scritto solo dall'amministratore, ma non è
+necessario chiamare l'amministratore per cambiare la propria password. Infatti
+il comando \cmd{passwd} appartiene in genere all'utente \textit{root} ma ha il
+bit \acr{suid} impostato, per cui quando viene lanciato da un utente normale
+ottiene comunque i privilegi di amministratore.
+
+Chiaramente avere un processo che ha privilegi superiori a quelli che avrebbe
+normalmente l'utente che lo ha lanciato comporta vari rischi, e questo tipo di
+programmi devono essere scritti accuratamente per evitare che possano essere
+usati per guadagnare privilegi non consentiti (l'argomento è affrontato in
+dettaglio in sez.~\ref{sec:proc_perms}).
+
+La presenza dei bit \acr{suid} e \acr{sgid} su un file può essere rilevata con
+il comando \cmd{ls -l}, che visualizza una lettera ``\cmd{s}'' al posto della
+``\cmd{x}'' in corrispondenza dei permessi di utente o gruppo. La stessa
+lettera ``\cmd{s}'' può essere usata nel comando \cmd{chmod} per impostare
+questi bit. Infine questi bit possono essere controllati all'interno di
+\var{st\_mode} con l'uso delle due costanti \const{S\_ISUID} e
+\const{S\_IGID}, i cui valori sono riportati in
+tab.~\ref{tab:file_mode_flags}.
+
+Gli stessi bit vengono ad assumere un significato completamente diverso per le
+directory, normalmente infatti Linux usa la convenzione di SVr4 per indicare
+con questi bit l'uso della semantica BSD nella creazione di nuovi file (si
+veda sez.~\ref{sec:file_ownership_management} per una spiegazione dettagliata
+al proposito).
+
+Infine Linux utilizza il bit \acr{sgid} per un'ulteriore estensione mutuata da
+SVr4. Il caso in cui un file ha il bit \acr{sgid} impostato senza che lo sia
+anche il corrispondente bit di esecuzione viene utilizzato per attivare per
+quel file il \textit{mandatory locking} (affronteremo questo argomento in
+dettaglio più avanti, in sez.~\ref{sec:file_mand_locking}).
+
+\itindend{suid~bit}
+\itindend{sgid~bit}
+
+\itindbeg{sticky~bit}
+
+L'ultimo dei bit rimanenti, identificato dalla costante \const{S\_ISVTX}, è in
+parte un rimasuglio delle origini dei sistemi Unix. A quell'epoca infatti la
+memoria virtuale e l'accesso ai file erano molto meno sofisticati e per
+ottenere la massima velocità possibile per i programmi usati più comunemente
+si poteva impostare questo bit.
+
+L'effetto di questo bit era che il segmento di testo del programma (si veda
+sez.~\ref{sec:proc_mem_layout} per i dettagli) veniva scritto nella swap la
+prima volta che questo veniva lanciato, e vi permaneva fino al riavvio della
+macchina (da questo il nome di \textsl{sticky bit}); essendo la swap un file
+continuo o una partizione indicizzata direttamente si poteva risparmiare in
+tempo di caricamento rispetto alla ricerca attraverso la struttura del
+filesystem. Lo \textsl{sticky bit} è indicato usando la lettera ``\texttt{t}''
+al posto della ``\texttt{x}'' nei permessi per gli altri.
+
+Ovviamente per evitare che gli utenti potessero intasare la swap solo
+l'amministratore era in grado di impostare questo bit, che venne chiamato
+anche con il nome di \textit{saved text bit}, da cui deriva quello della
+costante. Le attuali implementazioni di memoria virtuale e filesystem rendono
+sostanzialmente inutile questo procedimento.
+
+Benché ormai non venga più utilizzato per i file, lo \textit{sticky bit} ha
+invece assunto un uso importante per le directory;\footnote{lo \textit{sticky
+ bit} per le directory è un'estensione non definita nello standard POSIX,
+ Linux però la supporta, così come BSD e SVr4.} in questo caso se tale bit è
+impostato un file potrà essere rimosso dalla directory soltanto se l'utente ha
+il permesso di scrittura su di essa ed inoltre è vera una delle seguenti
+condizioni:
+\begin{itemize*}
+\item l'utente è proprietario del file,
+\item l'utente è proprietario della directory,
+\item l'utente è l'amministratore.
+\end{itemize*}
+
+Un classico esempio di directory che ha questo bit impostato è \file{/tmp}, i
+cui permessi infatti di solito sono i seguenti:
+\begin{Console}
+piccardi@hain:~/gapil$ \textbf{ls -ld /tmp}
+drwxrwxrwt 6 root root 1024 Aug 10 01:03 /tmp
+\end{Console}
+%$
+quindi con lo \textit{sticky bit} bit impostato. In questo modo qualunque
+utente nel sistema può creare dei file in questa directory, che come
+suggerisce il nome è normalmente utilizzata per la creazione di file
+temporanei, ma solo l'utente che ha creato un certo file potrà cancellarlo o
+rinominarlo. In questo modo si evita che un utente possa, più o meno
+consapevolmente, cancellare i file temporanei creati degli altri utenti.
+
+\itindend{sticky~bit}
+
+
+
+\subsection{Le funzioni per la gestione dei permessi dei file}
+\label{sec:file_perm_management}
+
+Come visto in sez.~\ref{sec:file_perm_overview} il controllo di accesso ad un
+file viene fatto utilizzando l'\ids{UID} ed il \ids{GID} effettivo del
+processo; ci sono casi però in cui si può voler effettuare il controllo con
+l'\ids{UID} reale ed il \ids{GID} reale, vale a dire usando i valori di
+\ids{UID} e \ids{GID} relativi all'utente che ha lanciato il programma, e che,
+come accennato in sez.~\ref{sec:file_special_perm} e spiegato in dettaglio in
+sez.~\ref{sec:proc_perms}, non è detto siano uguali a quelli effettivi.
+
+Per far questo si può usare la funzione di sistema \funcd{access}, il cui
+prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int access(const char *pathname, int mode)}
+\fdesc{Verifica i permessi di accesso.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] l'accesso al file non è consentito, o non si ha il
+ permesso di attraversare una delle directory di \param{pathname}.
+ \item[\errcode{EINVAL}] il valore di \param{mode} non è valido.
+ \item[\errcode{EROFS}] si è richiesto l'accesso in scrittura per un file su
+ un filesystem montato in sola lettura.
+ \item[\errcode{ETXTBSY}] si è richiesto l'accesso in scrittura per un
+ eseguibile binario correntemente in esecuzione.
+ \end{errlist}
+ ed inoltre \errval{EFAULT}, \errval{EIO}, \errval{ELOOP},
+ \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR} nel loro
+ significato generico.}
+\end{funcproto}
+
+La funzione verifica i permessi di accesso, indicati da \param{mode}, per il
+file indicato da \param{pathname}. I valori possibili per l'argomento
+\param{mode} sono esprimibili come combinazione delle costanti numeriche
+riportate in tab.~\ref{tab:file_access_mode_val} (attraverso un OR binario
+delle stesse). I primi tre valori implicano anche la verifica dell'esistenza
+del file, se si vuole verificare solo quest'ultima si può usare \const{F\_OK},
+o anche direttamente \func{stat}. Nel caso in cui \param{pathname} si
+riferisca ad un collegamento simbolico, questo viene seguito ed il controllo è
+fatto sul file a cui esso fa riferimento.
+
+La funzione controlla solo i bit dei permessi di accesso per \param{pathname},
+ma occorre poter risolvere quest'ultimo, e se non c'è il permesso di
+esecuzione per una qualunque delle sue componenti la funzione fallirà
+indipendentemente dai permessi del file. Si tenga presente poi che il fatto
+che una directory abbia permesso di scrittura non significa che vi si possa
+scrivere come fosse un file, e che se un file ha il permesso di esecuzione non
+è detto che sia eseguibile. La funzione ha successo solo se tutti i permessi
+controllati sono disponibili.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}{|c|l|}
+ \hline
+ \textbf{\param{mode}} & \textbf{Significato} \\
+ \hline
+ \hline
+ \constd{R\_OK} & Verifica il permesso di lettura. \\
+ \constd{W\_OK} & Verifica il permesso di scrittura. \\
+ \constd{X\_OK} & Verifica il permesso di esecuzione. \\
+ \constd{F\_OK} & Verifica l'esistenza del file. \\
+ \hline
+ \end{tabular}
+ \caption{Valori possibili per l'argomento \param{mode} della funzione
+ \func{access}.}
+ \label{tab:file_access_mode_val}
+\end{table}
+
+Un esempio tipico per l'uso di questa funzione è quello di un processo che sta
+eseguendo un programma coi privilegi di un altro utente (ad esempio attraverso
+l'uso del \textit{suid bit}) che vuole controllare se l'utente originale ha i
+permessi per accedere ad un certo file, ma eseguire questo controllo prima di
+aprire il file espone al rischio di una \textit{race condition} che apre ad un
+possibile \textit{symlink attack} fra il controllo e l'apertura del file. In
+questo caso è sempre opportuno usare invece la funzione \func{faccessat} che
+tratteremo insieme alle altre \textit{at-functions} in
+sez.~\ref{sec:file_openat}.
+
+
+Del tutto analoghe a \func{access} sono le due funzioni \funcm{euidaccess} e
+\funcm{eaccess} che ripetono lo stesso controllo usando però gli
+identificatori del gruppo effettivo, verificando quindi le effettive capacità
+di accesso ad un file. Le funzioni hanno entrambe lo stesso
+prototipo\footnote{in realtà \funcm{eaccess} è solo un sinonimo di
+ \funcm{euidaccess} fornita per compatibilità con l'uso di questo nome in
+ altri sistemi.} che è del tutto identico a quello di \func{access}. Prendono
+anche gli stessi valori e restituiscono gli stessi risultati e gli stessi
+codici di errore.
+
+Le due funzioni non sono previste da nessuno standard, ed utilizzabili solo
+avendo definito \macro{\_GNU\_SOURCE}; inoltre qualora le si vogliano
+utilizzare per verificare che un processo abbia i permessi per accedere ad un
+file prima di farlo effettivamente, ci si esporrebbe ad una \textit{race
+ condition}, dato che i permessi potrebbero cambiare nell'intervallo fra il
+controllo e l'accesso effettivo. Per questo motivo in questo caso è molto più
+semplice e sicuro tentare direttamente l'accesso, e trattare opportunamente
+l'eventuale fallimento per mancanza di permessi.
+
+Per cambiare i permessi di un file sono invece disponibili due funzioni di
+sistema \funcd{chmod} e \funcd{fchmod}, che operano rispettivamente usando il
+\textit{pathname} di un file o se questo è già aperto sul relativo file
+descriptor; i loro prototipi sono:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/stat.h}
+\fdecl{int chmod(const char *path, mode\_t mode)}
+\fdesc{Cambia i permessi del file indicato da \param{path} al valore indicato
+ da \param{mode}.}
+\fdecl{int fchmod(int fd, mode\_t mode)}
+\fdesc{Analoga alla precedente, ma usa il file descriptor \param{fd} per
+ indicare il file.}
+
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EPERM}] l'\ids{UID} effettivo non corrisponde a quello del
+ proprietario del file o non si hanno i privilegi di amministratore.
+ \item[\errcode{EROFS}] il file è su un filesystem in sola lettura.
+ \end{errlist}
+ ed inoltre per entrambe \errval{EIO}, per \func{chmod} \errval{EACCES},
+ \errval{EFAULT}, \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{ENOMEM}, \errval{ENOTDIR}, per \func{fchmod} \errval{EBADF} nel loro
+ significato generico.}
+\end{funcproto}
+
+
+Entrambe le funzioni utilizzano come secondo argomento \param{mode}, una
+variabile dell'apposito tipo primitivo \type{mode\_t} (vedi
+tab.~\ref{tab:intro_primitive_types}), che è una maschera binaria da
+utilizzare per specificare i permessi sui file.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|c|c|l|}
+ \hline
+ \textbf{\param{mode}} & \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{S\_ISUID} & 04000 & Set user ID bit.\\
+ \const{S\_ISGID} & 02000 & Set group ID bit.\\
+ \const{S\_ISVTX} & 01000 & Sticky bit.\\
+ \hline
+ \const{S\_IRWXU} & 00700 & L'utente ha tutti i permessi.\\
+ \const{S\_IRUSR} & 00400 & L'utente ha il permesso di lettura.\\
+ \const{S\_IWUSR} & 00200 & L'utente ha il permesso di scrittura.\\
+ \const{S\_IXUSR} & 00100 & L'utente ha il permesso di esecuzione.\\
+ \hline
+ \const{S\_IRWXG} & 00070 & Il gruppo ha tutti i permessi.\\
+ \const{S\_IRGRP} & 00040 & Il gruppo ha il permesso di lettura.\\
+ \const{S\_IWGRP} & 00020 & Il gruppo ha il permesso di scrittura.\\
+ \const{S\_IXGRP} & 00010 & Il gruppo ha il permesso di esecuzione.\\
+ \hline
+ \const{S\_IRWXO} & 00007 & Gli altri hanno tutti i permessi.\\
+ \const{S\_IROTH} & 00004 & Gli altri hanno il permesso di lettura.\\
+ \const{S\_IWOTH} & 00002 & Gli altri hanno il permesso di scrittura.\\
+ \const{S\_IXOTH} & 00001 & Gli altri hanno il permesso di esecuzione.\\
+ \hline
+ \end{tabular}
+ \caption{Valori delle costanti usate per indicare i vari bit di
+ \param{mode} utilizzato per impostare i permessi dei file.}
+ \label{tab:file_permission_const}
+\end{table}
+
+Si sono riportate in tab.~\ref{tab:file_permission_const} le costanti con cui
+indicare i singoli bit di \param{mode}; si noti come corrispondano agli stessi
+valori usati per \var{st\_mode} già visti in tab.~\ref{tab:file_mode_flags}.
+Il valore di \param{mode} può essere ottenuto combinando fra loro con un OR
+binario le costanti simboliche relative ai vari bit, o specificato
+direttamente, come per l'omonimo comando di shell \texttt{chmod}, con un
+valore numerico (con la shell in genere lo si scrive in ottale, dato che i bit
+dei permessi sono divisibili in gruppi di tre), che si può calcolare
+direttamente usando lo schema di utilizzo dei bit illustrato in
+fig.~\ref{fig:file_perm_bit}.
+
+Ad esempio i permessi standard assegnati ai nuovi file (lettura e scrittura
+per il proprietario, sola lettura per il gruppo e gli altri) sono
+corrispondenti al valore ottale \texttt{0644}, un programma invece avrebbe
+anche il bit di esecuzione attivo, con un valore ottale di \texttt{0755}, se
+infine si volesse attivare anche il bit \acr{suid} il valore ottale da fornire
+sarebbe \texttt{4755}.
+
+Il cambiamento dei permessi di un file eseguito attraverso queste funzioni ha
+comunque alcune limitazioni, previste per motivi di sicurezza. L'uso delle
+funzioni infatti è possibile solo se l'\ids{UID} effettivo del processo
+chiamante corrisponde a quello del proprietario del file o se il processo ha i
+privilegi di amministratore,\footnote{per la precisione la capacità
+ \const{CAP\_FOWNER}, vedi sez.~\ref{sec:proc_capabilities}.} in caso
+contrario esse falliranno con un errore di \errcode{EPERM}.
+
+Ma oltre a questa regola generale, di immediata comprensione, esistono delle
+limitazioni ulteriori. Per questo motivo, anche se si è proprietari del file,
+non tutti i valori possibili di \param{mode} sono permessi o hanno effetto;
+in particolare accade che:
+\begin{enumerate*}
+\item siccome solo l'amministratore può impostare lo \textit{sticky bit}, se
+ l'\ids{UID} effettivo del processo non è zero esso viene automaticamente
+ cancellato, senza notifica di errore, qualora sia stato indicato
+ in \param{mode}.
+\item per quanto detto in sez.~\ref{sec:file_ownership_management} riguardo la
+ creazione dei nuovi file, si può avere il caso in cui il file creato da un
+ processo è assegnato ad un gruppo per il quale il processo non ha privilegi.
+ Per evitare che si possa assegnare il bit \acr{sgid} ad un file appartenente
+ ad un gruppo per cui non si hanno diritti, questo viene automaticamente
+ cancellato da \param{mode}, senza notifica di errore, qualora il gruppo del
+ file non corrisponda a quelli associati al processo; la cosa non avviene
+ quando l'\ids{UID} effettivo del processo è zero.
+\end{enumerate*}
+
+Per alcuni filesystem\footnote{i filesystem più comuni (\acr{ext2},
+ \acr{ext3}, \acr{ext4}, \acr{XFS}, \acr{Btrfs}) supportano
+ questa caratteristica, che è mutuata da BSD.} è inoltre prevista
+un'ulteriore misura di sicurezza, volta a scongiurare l'abuso dei bit
+\acr{suid} e \acr{sgid}; essa consiste nel cancellare automaticamente questi
+bit dai permessi di un file qualora un processo che non appartenga
+all'amministratore\footnote{per la precisione un processo che non dispone
+ della capacità \const{CAP\_FSETID}, vedi sez.~\ref{sec:proc_capabilities}.}
+effettui una scrittura. In questo modo anche se un utente malizioso scopre un
+file \acr{suid} su cui può scrivere, un'eventuale modifica comporterà la
+perdita di questo privilegio.
+
+Le funzioni \func{chmod} e \func{fchmod} ci permettono di modificare i
+permessi di un file, resta però il problema di quali sono i permessi assegnati
+quando il file viene creato. Le funzioni dell'interfaccia nativa di Unix, come
+vedremo in sez.~\ref{sec:file_open_close}, permettono di indicare
+esplicitamente i permessi di creazione di un file, ma questo non è possibile
+per le funzioni dell'interfaccia standard ANSI C che non prevede l'esistenza
+di utenti e gruppi, ed inoltre il problema si pone anche per l'interfaccia
+nativa quando i permessi non vengono indicati esplicitamente.
+
+\itindbeg{umask}
+
+Per le funzioni dell'interfaccia standard ANSI C l'unico riferimento possibile
+è quello della modalità di apertura del nuovo file (lettura/scrittura o sola
+lettura), che però può fornire un valore che è lo stesso per tutti e tre i
+permessi di sez.~\ref{sec:file_perm_overview} (cioè $666$ nel primo caso e
+$222$ nel secondo). Per questo motivo il sistema associa ad ogni
+processo\footnote{è infatti contenuta nel campo \var{umask} della struttura
+ \kstruct{fs\_struct}, vedi fig.~\ref{fig:proc_task_struct}.} una maschera
+di bit, la cosiddetta \textit{umask}, che viene utilizzata per impedire che
+alcuni permessi possano essere assegnati ai nuovi file in sede di creazione. I
+bit indicati nella maschera vengono infatti cancellati dai permessi quando un
+nuovo file viene creato.\footnote{l'operazione viene fatta sempre: anche
+ qualora si indichi esplicitamente un valore dei permessi nelle funzioni di
+ creazione che lo consentono, i permessi contenuti nella \textit{umask}
+ verranno tolti.}
+
+La funzione di sistema che permette di impostare il valore di questa maschera
+di controllo è \funcd{umask}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stat.h}
+\fdecl{mode\_t umask(mode\_t mask)}
+\fdesc{Imposta la maschera dei permessi.}
+}
+
+{La funzione ritorna il precedente valore della maschera, non sono previste
+ condizioni di errore.}
+\end{funcproto}
+
+La funzione imposta la maschera dei permessi dei bit al valore specificato
+da \param{mask}, di cui vengono presi solo i 9 bit meno significativi. In
+genere si usa questa maschera per impostare un valore predefinito che escluda
+preventivamente alcuni permessi, il caso più comune è eliminare il permesso di
+scrittura per il gruppo e gli altri, corrispondente ad un valore
+per \param{mask} pari a $022$. In questo modo è possibile cancellare
+automaticamente i permessi non voluti. Di norma questo valore viene impostato
+una volta per tutte al login (a $022$ se non indicato altrimenti), e gli
+utenti non hanno motivi per modificarlo.
+
+\itindend{umask}
+
+
+\subsection{La gestione della titolarità dei file}
+\label{sec:file_ownership_management}
+
+Vedremo in sez.~\ref{sec:file_open_close} con quali funzioni si possono creare
+nuovi file, in tale occasione vedremo che è possibile specificare in sede di
+creazione quali permessi applicare ad un file, però non si può indicare a
+quale utente e gruppo esso deve appartenere. Lo stesso problema si presenta
+per la creazione di nuove directory (procedimento descritto in
+sez.~\ref{sec:file_dir_creat_rem}).
+
+Lo standard POSIX prescrive che l'\ids{UID} del nuovo file corrisponda
+all'\ids{UID} effettivo del processo che lo crea; per il \ids{GID} invece
+prevede due diverse possibilità:
+\begin{itemize*}
+\item che il \ids{GID} del file corrisponda al \ids{GID} effettivo del
+ processo.
+\item che il \ids{GID} del file corrisponda al \ids{GID} della directory in
+ cui esso è creato.
+\end{itemize*}
+
+In genere BSD usa sempre la seconda possibilità, che viene per questo chiamata
+semantica BSD. Linux invece segue normalmente quella che viene chiamata
+semantica SVr4: di norma un nuovo file viene creato, seguendo la prima
+opzione, con il \ids{GID} del processo, se però la directory in cui viene
+creato ha il bit \acr{sgid} dei permessi impostato allora viene usata la
+seconda opzione. L'adozione di questa semantica però può essere controllata,
+all'interno di alcuni filesystem,\footnote{con il kernel 2.6.25 questi erano
+ \acr{ext2}, \acr{ext3}, \acr{ext4}, e \acr{XFS}.} con l'uso dell'opzione di
+montaggio \texttt{grpid}, che se attivata fa passare all'uso della semantica
+BSD.
+
+Usare la semantica BSD ha il vantaggio che il \ids{GID} viene sempre
+automaticamente propagato, restando coerente a quello della directory di
+partenza, in tutte le sotto-directory. La semantica SVr4 offre la possibilità
+di scegliere, ma per ottenere lo stesso risultato di coerenza che si ha con
+quella di BSD necessita che quando si creano nuove directory venga propagato
+il bit \acr{sgid}. Questo è il comportamento predefinito del comando
+\cmd{mkdir}, ed è in questo modo ad esempio che le varie distribuzioni
+assicurano che le sotto-directory create nella home di un utente restino
+sempre con il \ids{GID} del gruppo primario dello stesso.
+
+La presenza del bit \acr{sgid} è inoltre molto comoda quando si hanno
+directory contenenti file condivisi da un gruppo di utenti in cui possono
+scrivere tutti i membri dello stesso, dato che assicura che i file che gli
+utenti vi creano appartengano allo gruppo stesso. Questo non risolve però
+completamente i problemi di accesso da parte di altri utenti dello stesso
+gruppo, in quanto di default i permessi assegnati al gruppo non sono
+sufficienti per un accesso in scrittura; in questo caso si deve aver cura di
+usare prima della creazione dei file un valore per \textit{umask} lasci il
+permesso di scrittura per il gruppo.\footnote{in tal caso si può assegnare
+ agli utenti del gruppo una \textit{umask} di $002$, anche se la soluzione
+ migliore in questo caso è usare una ACL di default (vedi
+ sez.~\ref{sec:file_ACL}).}
+
+Come avviene nel caso dei permessi esistono anche delle appropriate funzioni
+di sistema, \funcd{chown}, \funcd{fchown} e \funcd{lchown}, che permettono di
+cambiare sia l'utente che il gruppo a cui un file appartiene; i rispettivi
+prototipi sono:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/stat.h}
+\fdecl{int chown(const char *path, uid\_t owner, gid\_t group)}
+\fdecl{int fchown(int fd, uid\_t owner, gid\_t group)}
+\fdecl{int lchown(const char *path, uid\_t owner, gid\_t group)}
+\fdesc{Cambiano proprietario e gruppo proprietario di un file.}
+}
+
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EPERM}] l'\ids{UID} effettivo non corrisponde a quello del
+ proprietario del file o non è zero, o utente e gruppo non sono validi.
+ \end{errlist}
+ ed inoltre per tutte \errval{EROFS} e \errval{EIO}, per \func{chown}
+ \errval{EACCES}, \errval{EFAULT}, \errval{ELOOP}, \errval{ENAMETOOLONG},
+ \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, per \func{fchown}
+ \errval{EBADF} nel loro significato generico.}
+\end{funcproto}
+
+Le funzioni cambiano utente e gruppo di appartenenza di un file ai valori
+specificati dalle variabili \param{owner} e \param{group}. Con Linux solo
+l'amministratore\footnote{o in generale un processo con la capacità
+ \const{CAP\_CHOWN}, vedi sez.~\ref{sec:proc_capabilities}.} può cambiare il
+proprietario di un file; in questo viene seguita la semantica usata da BSD che
+non consente agli utenti di assegnare i loro file ad altri utenti evitando
+eventuali aggiramenti delle quote. L'amministratore può cambiare sempre il
+gruppo di un file, il proprietario può cambiare il gruppo solo dei file che
+gli appartengono e solo se il nuovo gruppo è il suo gruppo primario o uno dei
+gruppi di cui fa parte.
+
+La funzione \func{chown} segue i collegamenti simbolici, per operare
+direttamente su un collegamento simbolico si deve usare la funzione
+\func{lchown}.\footnote{fino alla versione 2.1.81 in Linux \func{chown} non
+ seguiva i collegamenti simbolici, da allora questo comportamento è stato
+ assegnato alla funzione \func{lchown}, introdotta per l'occasione, ed è
+ stata creata una nuova \textit{system call} per \func{chown} che seguisse i
+ collegamenti simbolici.} La funzione \func{fchown} opera su un file aperto,
+essa è mutuata da BSD, ma non è nello standard POSIX. Un'altra estensione
+rispetto allo standard POSIX è che specificando $-1$ come valore per
+\param{owner} e \param{group} i valori restano immutati.
+
+Quando queste funzioni sono chiamate con successo da un processo senza i
+privilegi di amministratore entrambi i bit \acr{suid} e \acr{sgid} vengono
+cancellati. Questo non avviene per il bit \acr{sgid} nel caso in cui esso sia
+usato (in assenza del corrispondente permesso di esecuzione) per indicare che
+per il file è attivo il \textit{mandatory locking} (vedi
+sez.~\ref{sec:file_mand_locking}).
+
+
+\subsection{Un quadro d'insieme sui permessi}
+\label{sec:file_riepilogo}
+
+Avendo affrontato in maniera separata il comportamento delle varie funzioni
+che operano sui permessi dei file ed avendo trattato in sezioni diverse il
+significato dei singoli bit dei permessi, vale la pena di fare un riepilogo in
+cui si riassumano le caratteristiche di ciascuno di essi, in modo da poter
+fornire un quadro d'insieme.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|c|c|c|c|c|c|c|c|c|c|c|c|l|}
+ \hline
+ \multicolumn{3}{|c|}{special}&
+ \multicolumn{3}{|c|}{user}&
+ \multicolumn{3}{|c|}{group}&
+ \multicolumn{3}{|c|}{other}&
+ \multirow{2}{*}{\textbf{Significato per i file}} \\
+ \cline{1-12}
+ \texttt{s}&\texttt{s}&\texttt{t}&
+ \texttt{r}&\texttt{w}&\texttt{x}&
+ \texttt{r}&\texttt{w}&\texttt{x}&
+ \texttt{r}&\texttt{w}&\texttt{x}& \\
+ \hline
+ \hline
+ 1&-&-&-&-&1&-&-&-&-&-&-&Eseguito conferisce l'\ids{UID} effettivo dell'utente.\\
+ -&1&-&-&-&1&-&-&-&-&-&-&Eseguito conferisce il \ids{GID} effettivo del gruppo.\\
+ -&1&-&-&-&0&-&-&-&-&-&-&Il \textit{mandatory locking} è abilitato.\\
+ -&-&1&-&-&-&-&-&-&-&-&-&Non utilizzato.\\
+ -&-&-&1&-&-&-&-&-&-&-&-&Permesso di lettura per l'utente.\\
+ -&-&-&-&1&-&-&-&-&-&-&-&Permesso di scrittura per l'utente.\\
+ -&-&-&-&-&1&-&-&-&-&-&-&Permesso di esecuzione per l'utente.\\
+ -&-&-&-&-&-&1&-&-&-&-&-&Permesso di lettura per il gruppo.\\
+ -&-&-&-&-&-&-&1&-&-&-&-&Permesso di scrittura per il gruppo.\\
+ -&-&-&-&-&-&-&-&1&-&-&-&Permesso di esecuzione per il gruppo.\\
+ -&-&-&-&-&-&-&-&-&1&-&-&Permesso di lettura per tutti gli altri.\\
+ -&-&-&-&-&-&-&-&-&-&1&-&Permesso di scrittura per tutti gli altri.\\
+ -&-&-&-&-&-&-&-&-&-&-&1&Permesso di esecuzione per tutti gli altri.\\
+ \hline
+ \hline
+ \multicolumn{3}{|c|}{special}&
+ \multicolumn{3}{|c|}{user}&
+ \multicolumn{3}{|c|}{group}&
+ \multicolumn{3}{|c|}{other}&
+ \multirow{2}{*}{\textbf{Significato per le directory}} \\
+ \cline{1-12}
+ \texttt{s}&\texttt{s}&\texttt{t}&
+ \texttt{r}&\texttt{w}&\texttt{x}&
+ \texttt{r}&\texttt{w}&\texttt{x}&
+ \texttt{r}&\texttt{w}&\texttt{x}& \\
+ \hline
+ \hline
+ 1&-&-&-&-&-&-&-&-&-&-&-&Non utilizzato.\\
+ -&1&-&-&-&-&-&-&-&-&-&-&Propaga il gruppo ai nuovi file creati.\\
+ -&-&1&-&-&-&-&-&-&-&-&-&Solo il proprietario di un file può rimuoverlo.\\
+ -&-&-&1&-&-&-&-&-&-&-&-&Permesso di visualizzazione per l'utente.\\
+ -&-&-&-&1&-&-&-&-&-&-&-&Permesso di aggiornamento per l'utente.\\
+ -&-&-&-&-&1&-&-&-&-&-&-&Permesso di attraversamento per l'utente.\\
+ -&-&-&-&-&-&1&-&-&-&-&-&Permesso di visualizzazione per il gruppo.\\
+ -&-&-&-&-&-&-&1&-&-&-&-&Permesso di aggiornamento per il gruppo.\\
+ -&-&-&-&-&-&-&-&1&-&-&-&Permesso di attraversamento per il gruppo.\\
+ -&-&-&-&-&-&-&-&-&1&-&-&Permesso di visualizzazione per tutti gli altri.\\
+ -&-&-&-&-&-&-&-&-&-&1&-&Permesso di aggiornamento per tutti gli altri.\\
+ -&-&-&-&-&-&-&-&-&-&-&1&Permesso di attraversamento per tutti gli altri.\\
+ \hline
+ \end{tabular}
+ \caption{Tabella riassuntiva del significato dei bit dei permessi per un
+ file e directory.}
+ \label{tab:file_fileperm_bits}
+\end{table}
+
+Nella parte superiore di tab.~\ref{tab:file_fileperm_bits} si è riassunto il
+significato dei vari bit dei permessi per un file ordinario; per quanto
+riguarda l'applicazione dei permessi per proprietario, gruppo ed altri si
+ricordi quanto illustrato in sez.~\ref{sec:file_perm_overview}. Per
+compattezza, nella tabella si sono specificati i bit di \textit{suid},
+\textit{sgid} e \textit{sticky} con la notazione illustrata anche in
+fig.~\ref{fig:file_perm_bit}. Nella parte inferiore si sono invece riassunti
+i significati dei vari bit dei permessi per una directory; anche in questo
+caso si è riapplicato ai bit di \textit{suid}, \textit{sgid} e \textit{sticky}
+la notazione illustrata in fig.~\ref{fig:file_perm_bit}.
+
+Si ricordi infine che i permessi non hanno alcun significato per i
+collegamenti simbolici, mentre per i file di dispositivo hanno senso soltanto
+i permessi di lettura e scrittura, che si riflettono sulla possibilità di
+compiere dette operazioni sul dispositivo stesso.
+
+Nella tabella si è indicato con il carattere ``-'' il fatto che il valore del
+bit in questione non è influente rispetto a quanto indicato nella riga della
+tabella; la descrizione del significato fa riferimento soltanto alla
+combinazione di bit per i quali è stato riportato esplicitamente un valore.
+Si rammenti infine che il valore dei bit dei permessi non ha alcun effetto
+qualora il processo possieda i privilegi di amministratore.
+
+
+\section{Caratteristiche e funzionalità avanzate}
+\label{sec:file_dir_advances}
+
+Tratteremo qui alcune caratteristiche e funzionalità avanzate della gestione
+di file e directory, affrontando anche una serie di estensioni
+dell'interfaccia classica dei sistemi unix-like, principalmente utilizzate a
+scopi di sicurezza, che sono state introdotte nelle versioni più recenti di
+Linux.
+
+\subsection{Gli attributi estesi}
+\label{sec:file_xattr}
+
+\itindbeg{Extended~Attributes}
+
+Nelle sezioni precedenti abbiamo trattato in dettaglio le varie informazioni
+che il sistema mantiene negli \textit{inode}, e le varie funzioni che
+permettono di modificarle. Si sarà notato come in realtà queste informazioni
+siano estremamente ridotte. Questo è dovuto al fatto che Unix origina negli
+anni '70, quando le risorse di calcolo e di spazio disco erano minime. Con il
+venir meno di queste restrizioni è incominciata ad emergere l'esigenza di
+poter associare ai file delle ulteriori informazioni astratte (quelli che
+abbiamo chiamato genericamente \textsl{metadati}) che però non potevano
+trovare spazio nei dati classici mantenuti negli \textit{inode}.
+
+Per risolvere questo problema alcuni sistemi unix-like (e fra questi anche
+Linux) hanno introdotto un meccanismo generico, detto \textit{Extended
+ Attributes} che consente di associare delle informazioni ulteriori ai
+singoli file; ad esempio vengono usati per la gestione delle ACL, che
+tratteremo in sez.~\ref{sec:file_ACL} e per le \textit{file capabilities}, che
+vedremo in sez.~\ref{sec:proc_capabilities}. Gli \textsl{attributi estesi}
+(abbreviati in \textsl{xattr}) non sono altro che delle coppie nome/valore che
+sono associate permanentemente ad un oggetto sul filesystem, analoghi di
+quello che sono le variabili di ambiente (vedi sez.~\ref{sec:proc_environ})
+per un processo.
+
+Altri sistemi (come Solaris, MacOS e Windows) hanno adottato un meccanismo
+diverso in cui ad un file sono associati diversi flussi di dati, su cui
+possono essere mantenute ulteriori informazioni, che possono essere accedute
+con le normali operazioni di lettura e scrittura. Questi non vanno confusi con
+gli \textit{Extended Attributes} (anche se su Solaris hanno lo stesso nome),
+che sono un meccanismo molto più semplice, che pur essendo limitato (potendo
+contenere solo una quantità limitata di informazione) hanno il grande
+vantaggio di essere molto più semplici da realizzare, più
+efficienti,\footnote{cosa molto importante, specie per le applicazioni che
+ richiedono una gran numero di accessi, come le ACL.} e di garantire
+l'atomicità di tutte le operazioni.
+
+In Linux gli attributi estesi sono sempre associati al singolo \textit{inode}
+e l'accesso viene sempre eseguito in forma atomica, in lettura il valore
+corrente viene scritto su un buffer in memoria, mentre la scrittura prevede
+che ogni valore precedente sia sovrascritto.
+
+Si tenga presente che non tutti i filesystem supportano gli \textit{Extended
+ Attributes}; al momento della scrittura di queste dispense essi sono
+presenti solo sui vari \acr{extN}, \acr{ReiserFS}, \acr{JFS},
+\acr{XFS}, \acr{Btrfs}, \acr{Lustre} e \acr{OCFS2}. Inoltre a
+seconda della implementazione ci possono essere dei limiti sulla quantità di
+attributi che si possono utilizzare.\footnote{ad esempio nel caso di
+ \acr{ext2} ed \acr{ext3} è richiesto che essi siano contenuti
+ all'interno di un singolo blocco, pertanto con dimensioni massime pari a
+ 1024, 2048 o 4096 byte a seconda delle dimensioni di quest'ultimo impostate
+ in fase di creazione del filesystem, mentre con \textsl{XFS} e
+ \textsl{Btrfs} non ci sono limiti ed i dati vengono memorizzati in maniera
+ diversa (nell'\textit{inode} stesso, in un blocco a parte, o in una
+ struttura ad albero dedicata) per mantenerne la scalabilità; lasciamo i
+ dettagli dei vari filesystem alla documentazione accessibile con \texttt{man
+ xattr}.} Infine lo spazio utilizzato per mantenere gli attributi estesi
+viene tenuto in conto per il calcolo delle quote di utente e gruppo
+proprietari del file.
+
+Come meccanismo per mantenere informazioni aggiuntive associate al singolo
+file, gli \textit{Extended Attributes} possono avere usi anche molto diversi
+fra loro. Per poterli distinguere allora sono stati suddivisi in
+\textsl{classi}, a cui poter applicare requisiti diversi per l'accesso e la
+gestione. Per questo motivo il nome di un attributo deve essere sempre
+specificato nella forma \texttt{namespace.attribute}, dove \texttt{namespace}
+fa riferimento alla classe a cui l'attributo appartiene, mentre
+\texttt{attribute} è il nome ad esso assegnato. In tale forma il nome di un
+attributo esteso deve essere univoco. Al momento sono state definite le
+quattro classi di attributi riportate in
+tab.~\ref{tab:extended_attribute_class}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}{|l|p{8cm}|}
+ \hline
+ \textbf{Nome} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \texttt{security}&Gli \textit{extended security attributes}: vengono
+ utilizzati dalle estensioni di sicurezza del kernel (i
+ \textit{Linux Security Modules}), per le realizzazione
+ di meccanismi evoluti di controllo di accesso come
+ \textit{SELinux} o le \textit{capabilities} dei
+ file di sez.~\ref{sec:proc_capabilities}.\\
+ \texttt{system} & Gli \textit{extended system attributes}: sono usati
+ dal kernel per memorizzare dati di sistema associati ai
+ file come le ACL (vedi sez.~\ref{sec:file_ACL}) o le
+ \textit{capabilities} (vedi
+ sez.~\ref{sec:proc_capabilities}).\\
+ \texttt{trusted}& I \textit{trusted extended attributes}: vengono
+ utilizzati per poter realizzare in \textit{user space}
+ meccanismi che consentano di mantenere delle
+ informazioni sui file che non devono essere accessibili
+ ai processi ordinari.\\
+ \texttt{user} & Gli \textit{extended user attributes}: utilizzati per
+ mantenere informazioni aggiuntive sui file (come il
+ \textit{mime-type}, la codifica dei caratteri o del
+ file) accessibili dagli utenti.\\
+ \hline
+ \end{tabular}
+ \caption{I nomi utilizzati valore di \texttt{namespace} per distinguere le
+ varie classi di \textit{Extended Attributes}.}
+ \label{tab:extended_attribute_class}
+\end{table}
+
+
+Dato che uno degli usi degli \textit{Extended Attributes} è di impiegarli per
+realizzare delle estensioni al tradizionale meccanismo dei controlli di
+accesso di Unix (come le ACL, \textit{SELinux}, ecc.), l'accesso ai loro
+valori viene regolato in maniera diversa a seconda sia della loro classe che
+di quali, fra le estensioni che li utilizzano, sono poste in uso. In
+particolare, per ciascuna delle classi riportate in
+tab.~\ref{tab:extended_attribute_class}, si hanno i seguenti casi:
+\begin{basedescript}{\desclabelwidth{1.7cm}\desclabelstyle{\nextlinelabel}}
+\item[\texttt{security}] L'accesso agli \textit{extended security attributes}
+ dipende dalle politiche di sicurezza stabilite da loro stessi tramite
+ l'utilizzo di un sistema di controllo basato sui \textit{Linux Security
+ Modules} (ad esempio \textit{SELinux}). Pertanto l'accesso in lettura o
+ scrittura dipende dalle politiche di sicurezza implementate all'interno dal
+ modulo di sicurezza che si sta utilizzando al momento (ciascuno avrà le
+ sue). Se non è stato caricato nessun modulo di sicurezza l'accesso in
+ lettura sarà consentito a tutti i processi, mentre quello in scrittura solo
+ ai processi con privilegi amministrativi (per la precisione dotati della
+ capacità \const{CAP\_SYS\_ADMIN}, vedi sez.~\ref{sec:proc_capabilities}).
+
+\item[\texttt{system}] Anche l'accesso agli \textit{extended system
+ attributes} dipende dalle politiche di accesso che il kernel realizza
+ anche utilizzando gli stessi valori in essi contenuti. Ad esempio nel caso
+ delle ACL (vedi sez.~\ref{sec:file_ACL}) l'accesso è consentito in lettura
+ ai processi che hanno la capacità di eseguire una ricerca sul file (cioè
+ hanno il permesso di lettura sulla directory che contiene il file) ed in
+ scrittura al proprietario del file o ai processi dotati della capacità
+ \const{CAP\_FOWNER}, vale a dire una politica di accesso analoga a quella
+ impiegata per gli ordinari permessi dei file.
+
+\item[\texttt{trusted}] L'accesso ai \textit{trusted extended attributes}, sia
+ per la lettura che per la scrittura, è consentito soltanto ai processi con
+ privilegi amministrativi dotati della capacità \const{CAP\_SYS\_ADMIN}. In
+ questo modo si possono utilizzare questi attributi per realizzare in
+ \textit{user space} dei meccanismi di controllo che accedono ad informazioni
+ non disponibili ai processi ordinari.
+
+\item[\texttt{user}] L'accesso agli \textit{extended user attributes} è
+ regolato dai normali permessi dei file: occorre avere il permesso di lettura
+ per leggerli e quello di scrittura per scriverli o modificarli. Dato l'uso
+ di questi attributi si è scelto di applicare al loro accesso gli stessi
+ criteri che si usano per l'accesso al contenuto dei file (o delle directory)
+ cui essi fanno riferimento. Questa scelta vale però soltanto per i file e le
+ directory ordinarie, se valesse in generale infatti si avrebbe un serio
+ problema di sicurezza dato che esistono diversi oggetti sul filesystem per i
+ quali è normale avere il permesso di scrittura consentito a tutti gli
+ utenti, come i collegamenti simbolici, o alcuni file di dispositivo come
+ \texttt{/dev/null}. Se fosse possibile usare su di essi gli \textit{extended
+ user attributes} un utente qualunque potrebbe inserirvi dati a
+ piacere.\footnote{la cosa è stata notata su XFS, dove questo comportamento
+ permetteva, non essendovi limiti sullo spazio occupabile dagli
+ \textit{Extended Attributes}, di bloccare il sistema riempiendo il disco.}
+
+ La semantica del controllo di accesso indicata inoltre non avrebbe alcun
+ senso al di fuori di file e directory: i permessi di lettura e scrittura per
+ un file di dispositivo attengono alle capacità di accesso al dispositivo
+ sottostante,\footnote{motivo per cui si può formattare un disco anche se
+ \texttt{/dev} è su un filesystem in sola lettura.} mentre per i
+ collegamenti simbolici questi vengono semplicemente ignorati: in nessuno dei
+ due casi hanno a che fare con il contenuto del file, e nella discussione
+ relativa all'uso degli \textit{extended user attributes} nessuno è mai stato
+ capace di indicare una qualche forma sensata di utilizzo degli stessi per
+ collegamenti simbolici o file di dispositivo, e neanche per le \textit{fifo}
+ o i socket.
+
+ Per questo motivo essi sono stati completamente disabilitati per tutto ciò
+ che non sia un file regolare o una directory.\footnote{si può verificare la
+ semantica adottata consultando il file \texttt{fs/xattr.c} dei sorgenti
+ del kernel.} Inoltre per le directory è stata introdotta una ulteriore
+ restrizione, dovuta di nuovo alla presenza ordinaria di permessi di
+ scrittura completi su directory come \texttt{/tmp}. Per questo motivo, per
+ evitare eventuali abusi, se una directory ha lo \textit{sticky bit} attivo
+ sarà consentito scrivere i suoi \textit{extended user attributes} soltanto
+ se si è proprietari della stessa, o si hanno i privilegi amministrativi
+ della capacità \const{CAP\_FOWNER}.
+\end{basedescript}
+
+Le funzioni per la gestione degli attributi estesi, come altre funzioni di
+gestione avanzate specifiche di Linux, non fanno parte della \acr{glibc}, e
+sono fornite da una apposita libreria, \texttt{libattr}, che deve essere
+installata a parte;\footnote{la versione corrente della libreria è
+ \texttt{libattr1}.} pertanto se un programma le utilizza si dovrà indicare
+esplicitamente l'uso della suddetta libreria invocando il compilatore con
+l'opzione \texttt{-lattr}.
+
+Per leggere gli attributi estesi sono disponibili tre diverse funzioni di
+sistema, \funcd{getxattr}, \funcd{lgetxattr} e \funcd{fgetxattr}, che
+consentono rispettivamente di richiedere gli attributi relativi a un file, a
+un collegamento simbolico e ad un file descriptor; i rispettivi prototipi
+sono:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{attr/xattr.h}
+\fdecl{ssize\_t getxattr(const char *path, const char *name, void *value,
+ size\_t size)}
+\fdecl{ssize\_t lgetxattr(const char *path, const char *name, void *value,
+ size\_t size)}
+\fdecl{ssize\_t fgetxattr(int filedes, const char *name, void *value,
+ size\_t size)}
+\fdesc{Leggono il valore di un attributo esteso.}
+}
+
+{Le funzioni ritornano un intero positivo che indica la dimensione
+ dell'attributo richiesto in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{ENOATTR}] l'attributo richiesto non esiste.
+ \item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal
+ filesystem o sono disabilitati.
+ \item[\errcode{ERANGE}] la dimensione \param{size} del buffer \param{value}
+ non è sufficiente per contenere il risultato.
+ \end{errlist}
+ ed inoltre tutti gli errori delle analoghe della famiglia \func{stat} con lo
+ stesso significato, ed in particolare \errcode{EPERM} se non si hanno i
+ permessi di accesso all'attributo.}
+\end{funcproto}
+
+Le funzioni \func{getxattr} e \func{lgetxattr} prendono come primo argomento
+un \textit{pathname} che indica il file di cui si vuole richiedere un
+attributo, la sola differenza è che la seconda, se il \textit{pathname} indica
+un collegamento simbolico, restituisce gli attributi di quest'ultimo e non
+quelli del file a cui esso fa riferimento. La funzione \func{fgetxattr} prende
+invece come primo argomento un numero di file descriptor, e richiede gli
+attributi del file ad esso associato.
+
+Tutte e tre le funzioni richiedono di specificare nell'argomento \param{name}
+il nome dell'attributo di cui si vuole ottenere il valore. Il nome deve essere
+indicato comprensivo di prefisso del \textit{namespace} cui appartiene (uno
+dei valori di tab.~\ref{tab:extended_attribute_class}) nella forma
+\texttt{namespace.attributename}, come stringa terminata da un carattere NUL.
+Il valore dell'attributo richiesto verrà restituito nel buffer puntato
+dall'argomento \param{value} per una dimensione massima di \param{size} byte
+(gli attributi estesi possono essere costituiti arbitrariamente da dati
+testuali o binari); se quest'ultima non è sufficiente si avrà un errore di
+\errcode{ERANGE}.
+
+Per evitare di dover indovinare la dimensione di un attributo per tentativi si
+può eseguire una interrogazione utilizzando un valore nullo per \param{size};
+in questo caso non verrà letto nessun dato, ma verrà restituito come valore di
+ritorno della funzione chiamata la dimensione totale dell'attributo esteso
+richiesto, che si potrà usare come stima per allocare un buffer di dimensioni
+sufficienti.
+
+Si tenga conto che questa è comunque una stima perché anche se le funzioni
+restituiscono la dimensione esatta dell'attributo al momento in cui sono
+eseguite, questa potrebbe essere modificata in qualunque momento da un
+successivo accesso eseguito da un altro processo, pertanto si verifichi sempre
+il valore di ritorno ed il codice di errore della funzione usata, senza dare
+per scontato che essa abbia sempre successo.
+
+Un secondo gruppo di funzioni sono quelle che consentono di impostare il
+valore di un attributo esteso, le funzioni sono \funcd{setxattr},
+\funcd{lsetxattr} e \funcd{fsetxattr} e consentono di operare rispettivamente
+su un file, su un collegamento simbolico o utilizzando un file descriptor; i
+rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{attr/xattr.h}
+\fdecl{int setxattr(const char *path, const char *name, const void *value,\\
+ \phantom{int setxattr(}size\_t size, int flags)}
+\fdecl{int lsetxattr(const char *path, const char *name, const void *value,\\
+ \phantom{int lsetxattr(}size\_t size, int flags)}
+\fdecl{int fsetxattr(int filedes, const char *name, const void *value,\\
+ \phantom{int fsetxattr(}size\_t size, int flags)}
+\fdesc{Impostano il valore di un attributo esteso.}
+}
+
+{Le funzioni ritornano un $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EEXIST}] si è usato il flag \const{XATTR\_CREATE} ma
+ l'attributo esiste già.
+ \item[\errcode{ENOATTR}] si è usato il flag \const{XATTR\_REPLACE} e
+ l'attributo richiesto non esiste.
+ \item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal
+ filesystem o sono disabilitati.
+ \end{errlist}
+ ed inoltre tutti gli errori delle analoghe della famiglia \func{stat} con lo
+ stesso significato ed in particolare \errcode{EPERM} se non si hanno i
+ permessi di accesso all'attributo.}
+\end{funcproto}
+
+Le tre funzioni prendono come primo argomento un valore adeguato al loro scopo
+(un \textit{pathname} le prime due, un file descriptor la terza), usato in
+maniera del tutto identica a quanto visto in precedenza per le analoghe che
+leggono gli attributi estesi.
+
+Il secondo argomento, \param{name}, deve indicare, anche in questo caso con
+gli stessi criteri appena visti per le analoghe \func{getxattr},
+\func{lgetxattr} e \func{fgetxattr}, il nome (completo di suffisso)
+dell'attributo su cui si vuole operare. Il valore che verrà assegnato
+all'attributo dovrà essere preparato nel buffer puntato da \param{value}, e la
+sua dimensione totale (in byte) dovrà essere indicata dall'argomento
+\param{size}.
+
+Infine l'argomento \param{flag} consente di controllare le modalità di
+sovrascrittura dell'attributo esteso, esso può prendere due valori: con
+\constd{XATTR\_REPLACE} si richiede che l'attributo esista, nel qual caso
+verrà sovrascritto ed altrimenti si avrà errore; con \constd{XATTR\_CREATE} si
+richiede che l'attributo non esista, nel qual caso verrà creato, altrimenti si
+avrà errore ed il valore attuale non sarà modificato. Utilizzando per
+\param{flag} un valore nullo l'attributo verrà modificato se è già presente, o
+creato se non c'è.
+
+Le funzioni finora illustrate permettono di leggere o scrivere gli attributi
+estesi presenti su un file, ma sarebbe altrettanto utile poter sapere quali
+sono questi attributi; per questo sono disponibili le ulteriori tre funzioni
+di sistema \funcd{listxattr}, \funcd{llistxattr} e \funcd{flistxattr} i cui
+prototipi sono:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{attr/xattr.h}
+\fdecl{ssize\_t listxattr(const char *path, char *list, size\_t size)}
+\fdecl{ssize\_t llistxattr(const char *path, char *list, size\_t size)}
+\fdecl{ssize\_t flistxattr(int filedes, char *list, size\_t size)}
+\fdesc{Leggono la lista degli attributi estesi di un file.}
+}
+
+{Le funzioni ritornano un intero positivo che indica la dimensione della lista
+ in caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà
+ uno dei valori:
+ \begin{errlist}
+ \item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal
+ filesystem o sono disabilitati.
+ \item[\errcode{ERANGE}] la dimensione \param{size} del buffer \param{value}
+ non è sufficiente per contenere il risultato.
+ \end{errlist}
+ ed inoltre tutti gli errori delle analoghe della famiglia \func{stat} con lo
+ stesso significato ed in particolare \errcode{EPERM} se non si hanno i
+ permessi di accesso all'attributo.}
+\end{funcproto}
+
+Come per le precedenti le tre funzioni leggono gli attributi rispettivamente
+di un file, un collegamento simbolico o specificando un file descriptor, da
+specificare con il loro primo argomento. Gli altri due argomenti, identici per
+tutte e tre, indicano rispettivamente il puntatore \param{list} al buffer dove
+deve essere letta la lista e la dimensione \param{size} di quest'ultimo.
+
+La lista viene fornita come sequenza non ordinata dei nomi dei singoli
+attributi estesi (sempre comprensivi del prefisso della loro classe) ciascuno
+dei quali è terminato da un carattere nullo. I nomi sono inseriti nel buffer
+uno di seguito all'altro. Il valore di ritorno della funzione indica la
+dimensione totale della lista in byte.
+
+Come per le funzioni di lettura dei singoli attributi se le dimensioni del
+buffer non sono sufficienti si avrà un errore, ma è possibile ottenere dal
+valore di ritorno della funzione una stima della dimensione totale della lista
+usando per \param{size} un valore nullo.
+
+Infine per rimuovere semplicemente un attributo esteso, si ha a disposizione
+un ultimo gruppo di funzioni di sistema: \funcd{removexattr},
+\funcd{lremovexattr} e \funcd{fremovexattr}; i rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{attr/xattr.h}
+\fdecl{int removexattr(const char *path, const char *name)}
+\fdecl{int lremovexattr(const char *path, const char *name)}
+\fdecl{int fremovexattr(int filedes, const char *name)}
+\fdesc{Rimuovono un attributo esteso di un file.}
+}
+
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{ENOATTR}] l'attributo richiesto non esiste.
+ \item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal
+ filesystem o sono disabilitati.
+ \end{errlist}
+ ed inoltre tutti gli errori delle analoghe della famiglia \func{stat} con lo
+ stesso significato ed in particolare \errcode{EPERM} se non si hanno i
+ permessi di accesso all'attributo.}
+\end{funcproto}
+
+Le tre funzioni rimuovono un attributo esteso operando rispettivamente su di
+un file, su un collegamento simbolico o un file descriptor, che vengono
+specificati dal valore passato con il loro primo argomento. L'attributo da
+rimuovere deve essere anche in questo caso indicato con
+l'argomento \param{name} secondo le stesse modalità già illustrate in
+precedenza per le altre funzioni relative alla gestione degli attributi
+estesi.
+
+\itindend{Extended~Attributes}
+
+
+\subsection{Le \textit{Access Control List}}
+\label{sec:file_ACL}
+
+% la documentazione di sistema è nei pacchetti libacl1-dev e acl
+% vedi anche http://www.suse.de/~agruen/acl/linux-acls/online/
+
+\itindbeg{Access~Control~List~(ACL)}
+
+Il modello classico dei permessi di Unix, per quanto funzionale ed efficiente,
+è comunque piuttosto limitato e per quanto possa aver coperto per lunghi anni
+le esigenze più comuni con un meccanismo semplice e potente, non è in grado di
+rispondere in maniera adeguata a situazioni che richiedono una gestione più
+complessa dei permessi di accesso.\footnote{già un requisito come quello di
+ dare accesso in scrittura ad alcune persone ed in sola lettura ad altre non
+ si può soddisfare in maniera semplice.}
+
+Per questo motivo erano state progressivamente introdotte nelle varie versioni
+di Unix dei meccanismi di gestione dei permessi dei file più flessibili, nella
+forma delle cosiddette \textit{Access Control List} (indicate usualmente con
+la sigla ACL). Nello sforzo di standardizzare queste funzionalità era stato
+creato un gruppo di lavoro il cui scopo era estendere lo standard POSIX 1003
+attraverso due nuovi insiemi di specifiche, la POSIX 1003.1e per l'interfaccia
+di programmazione e la POSIX 1003.2c per i comandi di shell.
+
+Gli obiettivi del gruppo di lavoro erano però forse troppo ambizioni, e nel
+gennaio del 1998 i finanziamenti vennero ritirati senza che si fosse arrivati
+alla definizione dello standard richiesto. Dato però che una parte della
+documentazione prodotta era di alta qualità venne deciso di rilasciare al
+pubblico la diciassettesima bozza del documento, quella che va sotto il nome
+di \textit{POSIX 1003.1e Draft 17}, che è divenuta la base sulla quale si
+definiscono le cosiddette \textit{Posix ACL}.
+
+A differenza di altri sistemi, come ad esempio FreeBSD, nel caso di Linux si è
+scelto di realizzare le ACL attraverso l'uso degli \textit{Extended
+ Attributes} (appena trattati in sez.~\ref{sec:file_xattr}), e fornire tutte
+le relative funzioni di gestione tramite una libreria, \texttt{libacl} che
+nasconde i dettagli implementativi delle ACL e presenta ai programmi una
+interfaccia che fa riferimento allo standard POSIX 1003.1e.
+
+Anche in questo caso le funzioni di questa libreria non fanno parte della
+\acr{glibc} e devono essere installate a parte;\footnote{la versione corrente
+ della libreria è \texttt{libacl1}, e nel caso si usi Debian la si può
+ installare con il pacchetto omonimo e con il collegato \texttt{libacl1-dev}
+ per i file di sviluppo.} pertanto se un programma le utilizza si dovrà
+indicare esplicitamente l'uso della libreria \texttt{libacl} invocando il
+compilatore con l'opzione \texttt{-lacl}. Si tenga presente inoltre che le ACL
+devono essere attivate esplicitamente montando il filesystem\footnote{che deve
+ supportarle, ma questo è ormai vero per praticamente tutti i filesystem più
+ comuni, con l'eccezione di NFS per il quale esiste però il supporto per le
+ versioni NFSv2 e NFSv3 del protocollo, con NFSv4 esistono invece delle ACL
+ native che hanno una semantica diversa, su di esse possono mappare le ACL
+ POSIX, ma l'inverso è possibile solo in forma incompleta.} su cui le si
+vogliono utilizzare con l'opzione \texttt{acl} attiva. Dato che si tratta di
+una estensione è infatti opportuno utilizzarle soltanto laddove siano
+necessarie.
+
+Una ACL è composta da un insieme di voci, e ciascuna voce è a sua volta
+costituita da un \textsl{tipo}, da un eventuale \textsl{qualificatore} (deve
+essere presente soltanto per le voci di tipo \const{ACL\_USER} e
+\const{ACL\_GROUP}) e da un insieme di permessi. Ad ogni oggetto sul
+filesystem si può associare una ACL che ne governa i permessi di accesso,
+detta \textit{access ACL}. Inoltre per le directory si può impostare una ACL
+aggiuntiva, detta ``\textit{Default ACL}'', che serve ad indicare quale dovrà
+essere la ACL assegnata di default nella creazione di un file all'interno
+della directory stessa. Come avviene per i permessi le ACL possono essere
+impostate solo del proprietario del file, o da un processo con la capacità
+\const{CAP\_FOWNER}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}{|l|p{8cm}|}
+ \hline
+ \textbf{Tipo} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \constd{ACL\_USER\_OBJ}& Voce che contiene i diritti di accesso del
+ proprietario del file.\\
+ \constd{ACL\_USER} & Voce che contiene i diritti di accesso per
+ l'utente indicato dal rispettivo
+ qualificatore.\\
+ \constd{ACL\_GROUP\_OBJ}&Voce che contiene i diritti di accesso del
+ gruppo proprietario del file.\\
+ \constd{ACL\_GROUP} & Voce che contiene i diritti di accesso per
+ il gruppo indicato dal rispettivo
+ qualificatore.\\
+ \constd{ACL\_MASK} & Voce che contiene la maschera dei massimi
+ permessi di accesso che possono essere garantiti
+ da voci del tipo \const{ACL\_USER},
+ \const{ACL\_GROUP} e \const{ACL\_GROUP\_OBJ}.\\
+ \constd{ACL\_OTHER} & Voce che contiene i diritti di accesso di chi
+ non corrisponde a nessuna altra voce dell'ACL.\\
+ \hline
+ \end{tabular}
+ \caption{Le costanti che identificano i tipi delle voci di una ACL.}
+ \label{tab:acl_tag_types}
+\end{table}
+
+L'elenco dei vari tipi di voci presenti in una ACL, con una breve descrizione
+del relativo significato, è riportato in tab.~\ref{tab:acl_tag_types}. Tre di
+questi tipi, \const{ACL\_USER\_OBJ}, \const{ACL\_GROUP\_OBJ} e
+\const{ACL\_OTHER}, corrispondono direttamente ai tre permessi ordinari dei
+file (proprietario, gruppo proprietario e tutti gli altri) e per questo una
+ACL valida deve sempre contenere una ed una sola voce per ciascuno di questi
+tipi.
+
+Una ACL può poi contenere un numero arbitrario di voci di tipo
+\const{ACL\_USER} e \const{ACL\_GROUP}, ciascuna delle quali indicherà i
+permessi assegnati all'utente e al gruppo indicato dal relativo qualificatore.
+Ovviamente ciascuna di queste voci dovrà fare riferimento a un utente o a un
+gruppo diverso, e non corrispondenti a quelli proprietari del file. Inoltre se
+in una ACL esiste una voce di uno di questi due tipi, è obbligatoria anche la
+presenza di una ed una sola voce di tipo \const{ACL\_MASK}, che negli altri
+casi è opzionale.
+
+Una voce di tipo \const{ACL\_MASK} serve a mantenere la maschera dei permessi
+che possono essere assegnati tramite voci di tipo \const{ACL\_USER},
+\const{ACL\_GROUP} e \const{ACL\_GROUP\_OBJ}. Se in una di queste voci si
+fosse specificato un permesso non presente in \const{ACL\_MASK} questo
+verrebbe ignorato. L'uso di una ACL di tipo \const{ACL\_MASK} è di particolare
+utilità quando essa associata ad una \textit{Default ACL} su una directory, in
+quanto i permessi così specificati verranno ereditati da tutti i file creati
+nella stessa directory. Si ottiene così una sorta di \textit{umask} associata
+ad un oggetto sul filesystem piuttosto che a un processo.
+
+Dato che le ACL vengono a costituire una estensione dei permessi ordinari, uno
+dei problemi che si erano posti nella loro standardizzazione era appunto
+quello della corrispondenza fra questi e le ACL. Come accennato i permessi
+ordinari vengono mappati nelle tre voci di tipo \const{ACL\_USER\_OBJ},
+\const{ACL\_GROUP\_OBJ} e \const{ACL\_OTHER} che devono essere presenti in
+qualunque ACL; un cambiamento ad una di queste voci viene automaticamente
+riflesso sui permessi ordinari dei file e viceversa.\footnote{per permessi
+ ordinari si intende quelli mantenuti nell'\textit{inode}, che devono restare
+ dato che un filesystem può essere montato senza abilitare le ACL.}
+
+In realtà la mappatura è diretta solo per le voci \const{ACL\_USER\_OBJ} e
+\const{ACL\_OTHER}, nel caso di \const{ACL\_GROUP\_OBJ} questo vale soltanto
+se non è presente una voce di tipo \const{ACL\_MASK}, che è quanto avviene
+normalmente se non sono presenti ACL aggiuntive rispetto ai permessi
+ordinari. Se invece questa è presente verranno tolti dai permessi di
+\const{ACL\_GROUP\_OBJ} (cioè dai permessi per il gruppo proprietario del
+file) tutti quelli non presenti in \const{ACL\_MASK}.\footnote{questo diverso
+ comportamento a seconda delle condizioni è stato introdotto dalla
+ standardizzazione \textit{POSIX 1003.1e Draft 17} per mantenere il
+ comportamento invariato sui sistemi dotati di ACL per tutte quelle
+ applicazioni che sono conformi soltanto all'ordinario standard \textit{POSIX
+ 1003.1}.}
+
+Un secondo aspetto dell'incidenza delle ACL sul comportamento del sistema è
+quello relativo alla creazione di nuovi file,\footnote{o oggetti sul
+ filesystem, il comportamento discusso vale per le funzioni \func{open} e
+ \func{creat} (vedi sez.~\ref{sec:file_open_close}), \func{mkdir} (vedi
+ sez.~\ref{sec:file_dir_creat_rem}), \func{mknod} e \func{mkfifo} (vedi
+ sez.~\ref{sec:file_mknod}).} che come accennato può essere modificato dalla
+presenza di una \textit{Default ACL} sulla directory che andrà a contenerli.
+Se questa non c'è valgono le regole usuali illustrate in
+sez.~\ref{sec:file_perm_management}, per cui essi sono determinati dalla
+\textit{umask} del processo, e la sola differenza è che i permessi ordinari da
+esse risultanti vengono automaticamente rimappati anche su una ACL di accesso
+assegnata automaticamente al nuovo file, che contiene soltanto le tre
+corrispondenti voci di tipo \const{ACL\_USER\_OBJ}, \const{ACL\_GROUP\_OBJ} e
+\const{ACL\_OTHER}.
+
+Se invece è presente una ACL di default sulla directory che contiene il nuovo
+file, essa diventerà automaticamente anche la ACL di accesso di quest'ultimo,
+a meno di non aver indicato, nelle funzioni di creazione che lo consentono,
+uno specifico valore per i permessi ordinari.\footnote{tutte le funzioni
+ citate in precedenza supportano un argomento \var{mode} che indichi un
+ insieme di permessi iniziale.} In tal caso saranno eliminati dalle voci
+corrispondenti che deriverebbero dalla ACL di default, tutti i permessi non
+presenti in tale indicazione.
+
+Dato che questa è la ragione che ha portato alla loro creazione, la principale
+modifica introdotta nel sistema con la presenza della ACL è quella alle regole
+del controllo di accesso ai file che si sono illustrate in
+sez.~\ref{sec:file_perm_overview}. Come nel caso ordinario per il controllo
+vengono sempre utilizzati gli identificatori del gruppo \textit{effective} del
+processo, ma in caso di presenza di una ACL sul file, i passi attraverso i
+quali viene stabilito se il processo ha il diritto di accesso sono i seguenti:
+\begin{enumerate*}
+\item Se l'\ids{UID} del processo è nullo (se cioè si è l'amministratore)
+ l'accesso è sempre garantito senza nessun controllo.\footnote{più
+ precisamente se si devono avere le capacità \const{CAP\_DAC\_OVERRIDE} per
+ i file e \const{CAP\_DAC\_READ\_SEARCH} per le directory, vedi
+ sez.~\ref{sec:proc_capabilities}.}
+\item Se l'\ids{UID} del processo corrisponde al proprietario del file allora:
+ \begin{itemize*}
+ \item se la voce \const{ACL\_USER\_OBJ} contiene il permesso richiesto,
+ l'accesso è consentito;
+ \item altrimenti l'accesso è negato.
+ \end{itemize*}
+\item Se l'\ids{UID} del processo corrisponde ad un qualunque qualificatore
+ presente in una voce \const{ACL\_USER} allora:
+ \begin{itemize*}
+ \item se la voce \const{ACL\_USER} corrispondente e la voce
+ \const{ACL\_MASK} contengono entrambe il permesso richiesto, l'accesso è
+ consentito;
+ \item altrimenti l'accesso è negato.
+ \end{itemize*}
+\item Se è il \ids{GID} del processo o uno dei \ids{GID} supplementari
+ corrisponde al gruppo proprietario del file allora:
+ \begin{itemize*}
+ \item se la voce \const{ACL\_GROUP\_OBJ} e una eventuale voce
+ \const{ACL\_MASK} (se non vi sono voci di tipo \const{ACL\_GROUP} questa
+ può non essere presente) contengono entrambe il permesso richiesto,
+ l'accesso è consentito;
+ \item altrimenti l'accesso è negato.
+ \end{itemize*}
+\item Se è il \ids{GID} del processo o uno dei \ids{GID} supplementari
+ corrisponde ad un qualunque qualificatore presente in una voce
+ \const{ACL\_GROUP} allora:
+ \begin{itemize*}
+ \item se la voce \const{ACL\_GROUP} corrispondente e la voce
+ \const{ACL\_MASK} contengono entrambe il permesso richiesto, l'accesso è
+ consentito;
+ \item altrimenti l'accesso è negato.
+ \end{itemize*}
+\item Se la voce \const{ACL\_USER\_OBJ} contiene il permesso richiesto,
+ l'accesso è consentito, altrimenti l'accesso è negato.
+\end{enumerate*}
+
+I passi di controllo vengono eseguiti esattamente in questa sequenza, e la
+decisione viene presa non appena viene trovata una corrispondenza con gli
+identificatori del processo. Questo significa che i permessi presenti in una
+voce di tipo \const{ACL\_USER} hanno la precedenza sui permessi ordinari
+associati al gruppo proprietario del file (vale a dire su
+\const{ACL\_GROUP\_OBJ}).
+
+Per la gestione delle ACL lo standard \textit{POSIX 1003.1e Draft 17} ha
+previsto delle apposite funzioni ed tutta una serie di tipi di dati dedicati,
+arrivando fino a definire un tipo di dato e delle costanti apposite per
+identificare i permessi standard di lettura, scrittura ed esecuzione. Tutte
+le operazioni devono essere effettuate attraverso tramite questi tipi di dati,
+che incapsulano tutte le informazioni contenute nelle ACL.
+
+La prima di queste funzioni che prendiamo in esame (si ricordi che come per
+tutte le altre per poterla usare occorre invocare il compilatore con l'opzione
+\texttt{-l acl}) è \funcd{acl\_init}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/acl.h}
+\fdecl{acl\_t acl\_init(int count)}
+\fdesc{Inizializza un'area di lavoro per una ACL.}
+}
+
+{La funzione ritorna un oggetto di tipo \type{acl\_t} in caso di successo e
+ \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] il valore di \param{count} è negativo.
+ \item[\errcode{ENOMEM}] non c'è sufficiente memoria disponibile.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione alloca ed inizializza un'area di memoria che verrà usata per
+mantenere i dati di una ACL contenente fino ad un massimo di \param{count}
+voci. La funzione ritorna un valore di tipo \typed{acl\_t} da usare in tutte le
+altre funzioni che operano sulla ACL. La funzione si limita alla allocazione
+iniziale e non inserisce nessun valore nella ACL che resta vuota.
+
+Si tenga presente che pur essendo \typed{acl\_t} un tipo opaco che identifica
+``\textsl{l'oggetto}'' ACL, il valore restituito dalla funzione non è altro
+che un puntatore all'area di memoria allocata per i dati richiesti. Pertanto
+in caso di fallimento verrà restituito un puntatore nullo di tipo
+``\code{(acl\_t) NULL}'' e si dovrà, in questa come in tutte le funzioni
+seguenti che restituiscono un oggetto di tipo \type{acl\_t}, confrontare il
+valore di ritorno della funzione con \val{NULL} (anche se, a voler essere
+estremamente pignoli, si dovrebbe usare ``\code{(acl\_t) NULL}'', ma è
+sufficiente fare un confronto direttamente con \val{NULL} essendo cura del
+compilatore fare le conversioni necessarie).
+
+Una volta che si siano completate le operazioni sui dati di una ACL la memoria
+allocata per un oggetto \type{acl\_t} dovrà essere liberata esplicitamente
+attraverso una chiamata alla funzione \funcd{acl\_free}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/acl.h}
+\fdecl{int acl\_free(void *obj\_p)}
+\fdesc{Disalloca la memoria riservata per una ACL.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} può assumere solo il valore:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{obj\_p} non è valido.
+ \end{errlist}
+}
+\end{funcproto}
+
+Si noti come la funzione usi come argomento un puntatore di tipo ``\ctyp{void
+ *}'', essa infatti può essere usata non solo per liberare la memoria
+allocata per i dati di una ACL, ma anche per quella usata per creare le
+stringhe di descrizione testuale delle ACL o per ottenere i valori dei
+qualificatori della una voce di una ACL. L'uso del tipo generico ``\ctyp{void
+ *}'' consente di evitare di eseguire un \textit{cast} al tipo di dato di cui
+si vuole effettuare la disallocazione.
+
+Si tenga presente poi che oltre a \func{acl\_init} ci sono molte altre
+funzioni che possono allocare memoria per i dati delle ACL, è pertanto
+opportuno tenere traccia di tutte le chiamate a queste funzioni perché alla
+fine delle operazioni tutta la memoria allocata dovrà essere liberata con
+\func{acl\_free}.
+
+Una volta che si abbiano a disposizione i dati di una ACL tramite il
+riferimento ad oggetto di tipo \type{acl\_t} questi potranno essere copiati
+con la funzione \funcd{acl\_dup}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/acl.h}
+\fdecl{acl\_t acl\_dup(acl\_t acl)}
+\fdesc{Crea una copia di una ACL.}
+}
+
+{La funzione ritorna un oggetto di tipo \type{acl\_t} in caso di successo in
+ caso di successo e \val{NULL} per un errore, nel qual caso \var{errno}
+ assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] l'argomento \param{acl} non è un puntatore valido
+ per una ACL.
+ \item[\errcode{ENOMEM}] non c'è sufficiente memoria disponibile per eseguire
+ la copia.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione crea una copia dei dati della ACL indicata tramite l'argomento
+\param{acl}, allocando autonomamente tutto spazio necessario alla copia e
+restituendo un secondo oggetto di tipo \type{acl\_t} come riferimento a
+quest'ultima. Valgono per questo le stesse considerazioni fatte per il valore
+di ritorno di \func{acl\_init}, ed in particolare il fatto che occorrerà
+prevedere una ulteriore chiamata esplicita a \func{acl\_free} per liberare la
+memoria occupata dalla copia.
+
+Se si deve creare una ACL manualmente l'uso di \func{acl\_init} è scomodo,
+dato che la funzione restituisce una ACL vuota, una alternativa allora è usare
+\funcd{acl\_from\_mode} che consente di creare una ACL a partire da un valore
+di permessi ordinari, il prototipo della funzione è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/acl.h}
+\fdecl{acl\_t acl\_from\_mode(mode\_t mode)}
+\fdesc{Crea una ACL inizializzata con i permessi ordinari.}
+}
+
+{La funzione ritorna un oggetto di tipo \type{acl\_t} in caso di successo e
+ \val{NULL} per un errore, nel qual caso \var{errno} può assumere solo
+ il valore \errval{ENOMEM}.}
+\end{funcproto}
+
+
+La funzione restituisce una ACL inizializzata con le tre voci obbligatorie
+\const{ACL\_USER\_OBJ}, \const{ACL\_GROUP\_OBJ} e \const{ACL\_OTHER} già
+impostate secondo la corrispondenza ai valori dei permessi ordinari indicati
+dalla maschera passata nell'argomento \param{mode}. Questa funzione è una
+estensione usata dalle ACL di Linux e non è portabile, ma consente di
+semplificare l'inizializzazione in maniera molto comoda.
+
+Altre due funzioni che consentono di creare una ACL già inizializzata sono
+\funcd{acl\_get\_fd} e \funcd{acl\_get\_file}, che consentono di leggere la
+ACL di un file; i rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/acl.h}
+\fdecl{acl\_t acl\_get\_file(const char *path\_p, acl\_type\_t type)}
+\fdecl{acl\_t acl\_get\_fd(int fd)}
+\fdesc{Leggono i dati delle ACL di un file.}
+}
+
+{Le funzioni ritornano un oggetto di tipo \type{acl\_t} in caso di successo e
+ \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCESS}] non c'è accesso per una componente di
+ \param{path\_p} o si è richiesta una ACL di default per un file (solo per
+ \func{acl\_get\_file}).
+ \item[\errcode{EINVAL}] \param{type} non ha un valore valido (solo per
+ \func{acl\_get\_file}).
+ \item[\errcode{ENOTSUP}] il filesystem cui fa riferimento il file non
+ supporta le ACL.
+ \end{errlist}
+ ed inoltre \errval{ENOMEM} per entrambe, \errval{EBADF} per
+ \func{acl\_get\_fd}, e \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{ENOTDIR}, per \func{acl\_get\_file} nel loro significato generico. }
+\end{funcproto}
+
+Le due funzioni ritornano, con un oggetto di tipo \type{acl\_t}, il valore
+della ACL correntemente associata ad un file, che può essere identificato
+tramite un file descriptor usando \func{acl\_get\_fd} o con un
+\textit{pathname} usando \func{acl\_get\_file}.
+
+Nel caso di quest'ultima funzione, che può richiedere anche la ACL relativa ad
+una directory, il secondo argomento \param{type} consente di specificare se si
+vuole ottenere la ACL di default o quella di accesso. Questo argomento deve
+essere di tipo \typed{acl\_type\_t} e può assumere solo i due valori riportati
+in tab.~\ref{tab:acl_type}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}{|l|l|}
+ \hline
+ \textbf{Tipo} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \constd{ACL\_TYPE\_ACCESS} & Indica una ACL di accesso.\\
+ \constd{ACL\_TYPE\_DEFAULT}& Indica una ACL di default.\\
+ \hline
+ \end{tabular}
+ \caption{Le costanti che identificano il tipo di ACL.}
+ \label{tab:acl_type}
+\end{table}
+
+Si tenga presente che nel caso di \func{acl\_get\_file} occorrerà che il
+processo chiamante abbia privilegi di accesso sufficienti a poter leggere gli
+attributi estesi dei file (come illustrati in sez.~\ref{sec:file_xattr});
+inoltre una ACL di tipo \const{ACL\_TYPE\_DEFAULT} potrà essere richiesta
+soltanto per una directory, e verrà restituita solo se presente, altrimenti
+verrà restituita una ACL vuota.
+
+Infine si potrà creare una ACL direttamente dalla sua rappresentazione
+testuale con la funzione \funcd{acl\_from\_text}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/acl.h}
+\fdecl{acl\_t acl\_from\_text(const char *buf\_p)}
+\fdesc{Crea una ACL a partire dalla sua rappresentazione testuale.}
+}
+
+{La funzione ritorna un oggetto di tipo \type{acl\_t} in caso di successo e
+ \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno
+ dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] la rappresentazione testuale all'indirizzo
+ \param{buf\_p} non è valida.
+ \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare i dati.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione prende come argomento il puntatore ad un buffer dove si è inserita
+la rappresentazione testuale della ACL che si vuole creare, la memoria
+necessaria viene automaticamente allocata ed in caso di successo viene
+restituito come valore di ritorno un oggetto di tipo \type{acl\_t} con il
+contenuto della stessa, che, come per le precedenti funzioni, dovrà essere
+disallocato esplicitamente al termine del suo utilizzo.
+
+La rappresentazione testuale di una ACL è quella usata anche dai comandi
+ordinari per la gestione delle ACL (\texttt{getfacl} e \texttt{setfacl}), che
+prevede due diverse forme, estesa e breve, entrambe supportate da
+\func{acl\_from\_text}. La forma estesa prevede che sia specificata una voce
+per riga, nella forma:
+\begin{Example}
+tipo:qualificatore:permessi
+\end{Example}
+dove il tipo può essere uno fra \texttt{user}, \texttt{group}, \texttt{other}
+e \texttt{mask}. Il qualificatore è presente solo per \texttt{user} e
+\texttt{group} ed indica l'utente o il gruppo a cui la voce si riferisce,
+mentre i permessi sono espressi con una tripletta di lettere analoga a quella
+usata per i permessi dei file, vale a dire ``\texttt{r}'' per il permesso di
+lettura, ``\texttt{w}'' per il permesso di scrittura, ``\texttt{x}'' per il
+permesso di esecuzione (scritti in quest'ordine) e ``\texttt{-}'' per
+l'assenza del permesso.
+
+Un possibile esempio di rappresentazione della ACL di un file ordinario a cui,
+oltre ai permessi ordinari, si è aggiunto un altro utente con un accesso in
+lettura, è il seguente:
+\begin{Example}
+user::rw-
+group::r--
+other::r--
+user:piccardi:r--
+group:gapil:r--
+\end{Example}
+
+Va precisato che i due tipi \texttt{user} e \texttt{group} sono usati
+rispettivamente per indicare delle voci relative ad utenti e gruppi (cioè per
+voci di tipo \const{ACL\_USER\_OBJ} e \const{ACL\_USER} per \texttt{user} e
+\const{ACL\_GROUP\_OBJ} e \const{ACL\_GROUP} per \texttt{group}) applicate sia
+a quelli proprietari del file che a quelli generici. Quelle dei proprietari si
+riconoscono per l'assenza di un qualificatore, ed in genere si scrivono per
+prima delle altre. Il significato delle voci di tipo \texttt{mask} e
+\texttt{mark} è evidente. Usando questa forma estesa si possono anche inserire
+dei commenti nel testo precedendoli con il carattere ``\texttt{\#}''.
+
+La forma breve prevede invece la scrittura delle singole voci su una riga,
+separate da virgole; come specificatori del tipo di voce si possono usare le
+iniziali dei valori usati nella forma estesa (cioè ``\texttt{u}'',
+``\texttt{g}'', ``\texttt{o}'' e ``\texttt{m}''), mentre le altri parte della
+voce sono le stesse. In questo caso non sono consentiti permessi.
+
+Per la conversione inversa, che consente di ottenere la rappresentazione
+testuale di una ACL, sono invece disponibili due funzioni. La prima delle due,
+di uso più immediato, è \funcd{acl\_to\_text}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/acl.h}
+\fdecl{char *acl\_to\_text(acl\_t acl, ssize\_t *len\_p)}
+\fdesc{Produce la rappresentazione testuale di una ACL.}
+}
+
+{La funzione ritorna il puntatore ad una stringa con la rappresentazione
+ testuale della ACL in caso di successo e \var{NULL} per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] o \param{acl} non è un puntatore ad una ACL o la ACL
+ che esso indica non è valida o non può esser tradotta in forma testuale.
+ \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare i dati.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione restituisce il puntatore ad una stringa, terminata da un NUL,
+contenente la rappresentazione testuale in forma estesa della ACL passata come
+argomento, ed alloca automaticamente la memoria necessaria. Questa dovrà poi
+essere liberata, quando non più necessaria, con \func{acl\_free}. Se
+nell'argomento \param{len\_p} si passa come valore il puntatore ad una
+variabile intera, in questa verrà restituita (come \textit{value result
+ argument}) la dimensione della stringa con la rappresentazione testuale, non
+comprendente il carattere nullo finale.
+
+La seconda funzione, che permette di controllare con una gran dovizia di
+particolari la generazione della stringa contenente la rappresentazione
+testuale della ACL, è \funcd{acl\_to\_any\_text}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/acl.h}
+\fdecl{char *acl\_to\_any\_text(acl\_t acl, const char *prefix, char
+ separator, int options)}
+\fdesc{Produce la rappresentazione testuale di una ACL.}
+}
+
+{La funzione ritorna il puntatore ad una stringa con la rappresentazione
+ testuale della ACL in caso di successo e \val{NULL} per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] la ACL indicata da \param{acl} non è valida.
+ \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare i dati.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione converte in formato testo la ACL indicata dall'argomento
+\param{acl}, usando il carattere \param{separator} come separatore delle
+singole voci; se l'argomento \param{prefix} non è nullo la stringa da esso
+indicata viene utilizzata come prefisso per le singole voci.
+
+L'ultimo argomento, \param{options}, consente di controllare la modalità con
+cui viene generata la rappresentazione testuale. Un valore nullo fa sì che
+vengano usati gli identificatori standard \texttt{user}, \texttt{group},
+\texttt{other} e \texttt{mask} con i nomi di utenti e gruppi risolti rispetto
+ai loro valori numerici. Altrimenti si può specificare un valore in forma di
+maschera binaria, da ottenere con un OR aritmetico dei valori riportati in
+tab.~\ref{tab:acl_to_text_options}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}{|l|p{8cm}|}
+ \hline
+ \textbf{Tipo} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \constd{TEXT\_ABBREVIATE} & Stampa le voci in forma abbreviata.\\
+ \constd{TEXT\_NUMERIC\_IDS} & Non effettua la risoluzione di
+ \ids{UID} e \ids{GID} lasciando i valori
+ numerici.\\
+ \constd{TEXT\_SOME\_EFFECTIVE}&Per ciascuna voce che contiene permessi che
+ vengono eliminati dalla \const{ACL\_MASK}
+ viene generato un commento con i permessi
+ effettivamente risultanti; il commento è
+ separato con un tabulatore.\\
+ \constd{TEXT\_ALL\_EFFECTIVE}& Viene generato un commento con i permessi
+ effettivi per ciascuna voce che contiene
+ permessi citati nella \const{ACL\_MASK},
+ anche quando questi non vengono modificati
+ da essa; il commento è separato con un
+ tabulatore.\\
+ \constd{TEXT\_SMART\_INDENT} & Da usare in combinazione con le precedenti
+ opzioni \const{TEXT\_SOME\_EFFECTIVE} e
+ \const{TEXT\_ALL\_EFFECTIVE}, aumenta
+ automaticamente il numero di spaziatori
+ prima degli eventuali commenti in modo da
+ mantenerli allineati.\\
+ \hline
+ \end{tabular}
+ \caption{Possibili valori per l'argomento \param{options} di
+ \func{acl\_to\_any\_text}.}
+ \label{tab:acl_to_text_options}
+\end{table}
+
+Come per \func{acl\_to\_text} anche in questo caso il buffer contenente la
+rappresentazione testuale dell'ACL, di cui la funzione restituisce
+l'indirizzo, viene allocato automaticamente, e dovrà essere esplicitamente
+disallocato con una chiamata ad \func{acl\_free}. Si tenga presente infine che
+questa funzione è una estensione specifica di Linux, e non è presente nella
+bozza dello standard POSIX.1e.
+
+Per quanto utile per la visualizzazione o l'impostazione da riga di comando
+delle ACL, la forma testuale non è la più efficiente per poter memorizzare i
+dati relativi ad una ACL, ad esempio quando si vuole eseguirne una copia a
+scopo di archiviazione. Per questo è stata prevista la possibilità di
+utilizzare una rappresentazione delle ACL in una apposita forma binaria
+contigua e persistente. È così possibile copiare il valore di una ACL in un
+buffer e da questa rappresentazione tornare indietro e generare una ACL.
+
+Lo standard POSIX.1e prevede a tale scopo tre funzioni, la prima e più
+semplice è \funcd{acl\_size}, che consente di ottenere la dimensione che avrà
+la citata rappresentazione binaria, in modo da poter allocare per essa un
+buffer di dimensione sufficiente, il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/acl.h}
+\fdecl{ssize\_t acl\_size(acl\_t acl)}
+\fdesc{Determina la dimensione della rappresentazione binaria di una ACL.}
+}
+
+{La funzione ritorna la dimensione in byte della rappresentazione binaria
+ della ACL in caso di successo e $-1$ per un errore, nel qual caso
+ \var{errno} può assumere solo il valore:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] la ACL indicata da \param{acl} non è valida.
+ \end{errlist}
+}
+\end{funcproto}
+
+Ottenuta con \func{acl\_size} la dimensione del buffer necessaria per potervi
+memorizzare una ACL questo dovrà potrà essere allocato direttamente con
+\func{malloc}, ed a questo punto vi si potrà salvare la rappresentazione
+binaria della precedente ACL utilizzando la funzione \funcd{acl\_copy\_ext},
+il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/acl.h}
+\fdecl{ssize\_t acl\_copy\_ext(void *buf\_p, acl\_t acl, ssize\_t size)}
+\fdesc{Ottiene la rappresentazione binaria di una ACL.}
+}
+
+{La funzione ritorna la dimensione in byte della rappresentazione binaria
+ della ACL in caso di successo e $-1$ per un errore, nel qual caso
+ \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] la ACL indicata da \param{acl} non è valida, o
+ \param{acl} non è un puntatore ad una ACL o \param{size} è negativo o
+ nullo.
+ \item[\errcode{ERANGE}] il valore di \param{size} è più piccolo della
+ dimensione della rappresentazione binaria della ACL.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione scriverà la rappresentazione binaria della ACL indicata da
+\param{acl} sul buffer di dimensione \param{size} all'indirizzo
+\param{buf\_p}, restituendo la dimensione della stessa come valore di
+ritorno. Qualora la dimensione della rappresentazione ecceda il valore di
+\param{size} la funzione fallirà con un errore di \errcode{ERANGE}. La
+funzione non ha nessun effetto sulla ACL indicata da \param{acl}.
+
+Viceversa se si vuole ripristinare una ACL a partire da una rappresentazione
+binaria si potrà usare la funzione \funcd{acl\_copy\_int}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/acl.h}
+\fdecl{acl\_t acl\_copy\_int(const void *buf\_p)}
+\fdesc{Ripristina la rappresentazione binaria di una ACL.}
+}
+
+{La funzione ritorna un oggetto di tipo \type{acl\_t} in caso di successo e
+ \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] il buffer all'indirizzo \param{buf\_p} non contiene
+ una rappresentazione corretta di una ACL.
+ \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare un oggetto
+ \type{acl\_t} per la ACL richiesta.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione alloca autonomamente un oggetto di tipo \type{acl\_t}, restituito
+come valore di ritorno, con il contenuto della ACL rappresentata dai dati del
+buffer puntato da \param{buf\_p}. Al solito l'oggetto \type{acl\_t} dovrà
+essere disallocato esplicitamente al termine del suo utilizzo.
+
+Una volta che si disponga della ACL desiderata, questa potrà essere impostata
+su un file o una directory. Per impostare una ACL sono disponibili due
+funzioni: \funcd{acl\_set\_file}, che opera sia su file che su directory
+usando un \textit{pathname}, e \funcd{acl\_set\_file} che opera solo su file
+usando un file descriptor; i rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/acl.h}
+\fdecl{int acl\_set\_file(const char *path, acl\_type\_t type, acl\_t acl)}
+\fdesc{Imposta una ACL su un file o una directory.}
+\fdecl{int acl\_set\_fd(int fd, acl\_t acl)}
+\fdesc{Imposta una ACL su un file descriptor.}
+}
+
+{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] o un generico errore di accesso a \param{path} o il
+ valore di \param{type} specifica una ACL il cui tipo non può essere
+ assegnato a \param{path}.
+ \item[\errcode{EINVAL}] o \param{acl} non è una ACL valida, o \param{type}
+ ha un valore non corretto per \func{acl\_set\_file} o o ha più voci di
+ quante se ne possono assegnare al file per \func{acl\_set\_fd}.
+ \item[\errcode{ENOSPC}] non c'è spazio disco sufficiente per contenere i
+ dati aggiuntivi della ACL.
+ \item[\errcode{ENOTSUP}] si è cercato di impostare una ACL su un file
+ contenuto in un filesystem che non supporta le ACL.
+ \end{errlist}
+ ed inoltre nel loro significato generico \errval{EPERM}, \errval{EROFS} per
+ entrambe, \errval{EBADF} per \func{acl\_set\_fd}, \errval{ENAMETOOLONG},
+ \errval{ENOENT}, \errval{ENOTDIR} per \func{acl\_set\_file}.}
+\end{funcproto}
+
+Con \func{acl\_set\_file} si assegna la ACL contenuta in \param{acl} al file o
+alla directory indicate da \param{path}, con \param{type} che indica il tipo
+di ACL con le costanti di tab.~\ref{tab:acl_type}; si tenga presente però che
+le ACL di default possono essere solo impostate qualora \param{path} indichi
+una directory. Inoltre perché la funzione abbia successo la ACL dovrà essere
+valida, e contenere tutti le voci necessarie, con l'eccezione si specifica una
+ACL vuota per cancellare la ACL di default associata a \param{path}, valida
+solo in caso di directory.\footnote{questo però è una estensione della
+ implementazione delle ACL di Linux, la bozza di standard POSIX.1e prevedeva
+ l'uso della apposita funzione \funcd{acl\_delete\_def\_file}, che prende
+ come unico argomento il \textit{pathname} della directory di cui si vuole
+ cancellare l'ACL di default, per i dettagli si ricorra alla pagina di
+ manuale.}
+
+La seconda funzione, \func{acl\_set\_fd}, è del tutto è analoga alla prima, ma
+non dovendo avere a che fare con directory (e la conseguente possibilità di
+avere una ACL di default) non necessita che si specifichi il tipo di ACL, che
+sarà sempre di accesso, e prende come unico argomento, a parte il file
+descriptor, la ACL da impostare.
+
+Le funzioni viste finora operano a livello di una intera ACL, eseguendo in una
+sola volta tutte le operazioni relative a tutte le voci in essa contenuta. In
+generale è possibile modificare un singolo valore all'interno di una singola
+voce direttamente con le funzioni previste dallo standard POSIX.1e. Queste
+funzioni però sono alquanto macchinose da utilizzare per cui è molto più
+semplice operare direttamente sulla rappresentazione testuale. Questo è il
+motivo per non tratteremo nei dettagli dette funzioni, fornendone solo una
+descrizione sommaria; chi fosse interessato può ricorrere alle pagine di
+manuale.
+
+Se si vuole operare direttamente sui contenuti di un oggetto di tipo
+\type{acl\_t} infatti occorre fare riferimento alle singole voci tramite gli
+opportuni puntatori di tipo \typed{acl\_entry\_t}, che possono essere ottenuti
+dalla funzione \funcm{acl\_get\_entry} (per una voce esistente) o dalla
+funzione \funcm{acl\_create\_entry} per una voce da aggiungere. Nel caso della
+prima funzione si potrà poi ripetere la lettura per ottenere i puntatori alle
+singole voci successive alla prima.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/mygetfacl.c}
+ \end{minipage}
+ \normalsize
+ \caption{Corpo principale del programma \texttt{mygetfacl.c}.}
+ \label{fig:proc_mygetfacl}
+\end{figure}
+
+Una volta ottenuti detti puntatori si potrà operare sui contenuti delle
+singole voci: con le funzioni \funcm{acl\_get\_tag\_type},
+\funcm{acl\_get\_qualifier}, \funcm{acl\_get\_permset} si potranno leggere
+rispettivamente tipo, qualificatore e permessi, mentre con le corrispondenti
+\funcm{acl\_set\_tag\_type}, \funcm{acl\_set\_qualifier},
+\funcm{acl\_set\_permset} si potranno impostare i valori; in entrambi i casi
+vengono utilizzati tipi di dato ad hoc, descritti nelle pagine di manuale. Si
+possono poi copiare i valori di una voce da una ACL ad un altra con
+\funcm{acl\_copy\_entry} o eliminare una voce da una ACL con
+\funcm{acl\_delete\_entry} e verificarne la validità prima di usarla con
+\funcm{acl\_valid} o \funcm{acl\_check}.
+
+\itindend{Access~Control~List~(ACL)}
+
+Come esempio di utilizzo di queste funzioni nei sorgenti allegati alla guida
+si è distribuito il programma \texttt{mygetfacl.c}, che consente di leggere le
+ACL di un file, passato come argomento.
+
+La sezione principale del programma, da cui si è rimossa la sezione sulla
+gestione delle opzioni, è riportata in fig.~\ref{fig:proc_mygetfacl}. Il
+programma richiede un unico argomento (\texttt{\small 16-20}) che indica il
+file di cui si vuole leggere la ACL. Se questo è presente si usa
+(\texttt{\small 22}) la funzione \func{get\_acl\_file} per leggerne la ACL, e
+si controlla (\texttt{\small 23-26}) se l'operazione ha successo, uscendo con
+un messaggio di errore in caso contrario.
+
+Ottenuta la ACL la si converte in formato testuale (\texttt{\small 27}) con la
+funzione \func{acl\_to\_text}, controllando di nuovo se l'operazione ha
+successo (\texttt{\small 28-31}) ed uscendo in caso contrario. Si provvede
+infine a stampare la rappresentazione testuale (\texttt{\small 32}) e dopo
+aver liberato (\texttt{\small 33-34}) le risorse allocate automaticamente, si
+conclude l'esecuzione.
+
+
+\subsection{La gestione delle quote disco}
+\label{sec:disk_quota}
+
+Quella delle quote disco è una funzionalità introdotta inizialmente da BSD e
+presente in Linux fino dai kernel dalla serie 2.0, che consente di porre dei
+tetti massimi al consumo delle risorse di un filesystem (spazio disco e
+\textit{inode}) da parte di utenti e gruppi.
+
+Dato che la funzionalità ha senso solo per i filesystem su cui si mantengono i
+dati degli utenti essa deve essere attivata esplicitamente.\footnote{in genere
+ la si attiva sul filesystem che contiene le \textit{home} degli utenti, dato
+ che non avrebbe senso per i file di sistema che in genere appartengono
+ all'amministratore.} Questo si fa, per tutti i filesystem che le supportano,
+tramite due distinte opzioni di montaggio, \texttt{usrquota} e
+\texttt{grpquota}, che abilitano le quote rispettivamente per gli utenti e per
+i gruppi. Così è possibile usare le limitazioni delle quote o sugli utenti o
+sui gruppi o su entrambi.
+
+Dal kernel 4.1, ed inizialmente solo per il filesystem XFS, sono diventate
+disponibili un terzo tipo di quote, dette \textit{project quota}, che
+consentono di applicare delle quote ad un ``\textsl{progetto}'', identificato
+come ramo di albero sotto una directory, per il quale possono essere imposti
+dei limiti (di nuovo in termini di spazio disco o \textit{inode}) per i file
+che ne fanno parte. Si può così porre dei limiti sul contenuto di un ramo di
+albero.
+
+Il meccanismo prevede che per ciascun filesystem che supporta le quote disco
+(i vari \acr{extN}, \acr{Btrfs}, \acr{XFS}, \acr{JFS}, \acr{ReiserFS}) il
+kernel provveda sia a mantenere aggiornati i dati relativi al consumo delle
+risorse da parte degli utenti e dei gruppi (e del progetto), che a far
+rispettare i limiti imposti dal sistema, con la generazione di un errore di
+\errcode{EDQUOT} per tutte le operazioni sui file che porterebbero ad un
+superamento degli stessi. Si tenga presente che questi due compiti sono
+separati, il primo si attiva al montaggio del filesystem con il supporto per
+le quote, il secondo deve essere abilitato esplicitamente.
+
+Per il mantenimento dei dati di consumo delle risorse vengono usati due file
+riservati nella directory radice del filesystem su cui si sono attivate le
+quote, uno per le quote utente e l'altro per le quote gruppo.\footnote{la cosa
+ vale per tutti i filesystem tranne \textit{XFS} che mantiene i dati
+ internamente, compresi quelli per le \textit{project quota}, che pertanto,
+ essendo questo l'unico filesyste che le supporta, non hanno un file ad esse
+ riservato.} Con la versione 2 del supporto delle quote, che da anni è
+l'unica rimasta in uso, questi file sono \texttt{aquota.user} e
+\texttt{aquota.group}, in precedenza erano \texttt{quota.user} e
+\texttt{quota.group}.
+
+Dato che questi file vengono aggiornati soltanto se il filesystem è stato
+montato attivando il supporto delle quote, se si abilita il supporto in un
+secondo tempo e nel frattempo sono state eseguite delle operazioni sul
+filesystem quando il supporto era disabilitato, i dati contenuti possono non
+corrispondere esattamente allo stato corrente del consumo delle risorse. Per
+questo motivo prima di montare in scrittura un filesystem su cui sono
+abilitate le quote viene richiesto di utilizzare il comando \cmd{quotacheck}
+per verificare e aggiornare i dati.
+
+Le restrizioni sul consumo delle risorse previste dal sistema delle quote
+prevedono sempre la presenza di due diversi limiti, il primo viene detto
+\textit{soft limit} e può essere superato per brevi periodi di tempo senza che
+causare errori per lo sforamento delle quote, il secondo viene detto
+\textit{hard limit} e non può mai essere superato.
+
+Il periodo di tempo per cui è possibile eccedere rispetto alle restrizioni
+indicate dal \textit{soft limit} è detto ``\textsl{periodo di grazia}''
+(\textit{grace period}), che si attiva non appena si supera la quota da esso
+indicata. Se si continua a restare al di sopra del \textit{soft limit} una
+volta scaduto il \textit{grace period} questo verrà trattato allo stesso modo
+dell'\textit{hard limit} e si avrà l'emissione immediata di un errore.
+
+Si tenga presente infine che entrambi i tipi di limiti (\textit{soft limit} e
+\textit{hard limit}) possono essere disposti separatamente su entrambe le
+risorse di un filesystem, essi cioè possono essere presenti in maniera
+indipendente sia sullo spazio disco, con un massimo per il numero di blocchi,
+che sui file, con un massimo per il numero di \textit{inode}.
+
+La funzione di sistema che consente di controllare tutti i vari aspetti della
+gestione delle quote è \funcd{quotactl}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/quota.h}
+\fdecl{int quotactl(int cmd, const char *dev, int id, caddr\_t addr)}
+\fdesc{Esegue una operazione di controllo sulle quote disco.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] si è richiesto \const{Q\_QUOTAON}, ma il file delle
+ quote indicato da \param{addr} esiste ma non è un file ordinario o no sta
+ su \param{dev}.
+ \item[\errcode{EBUSY}] si è richiesto \const{Q\_QUOTAON}, ma le quote sono
+ già attive.
+ \item[\errcode{EFAULT}] \param{addr} o \param{dev} non sono un puntatori
+ validi.
+ \item[\errcode{EINVAL}] o \param{cmd} non è un comando valido,
+ o il dispositivo \param{dev} non esiste.
+ \item[\errcode{EIO}] errore di lettura/scrittura sul file delle quote.
+ \item[\errcode{EMFILE}] non si può aprire il file delle quote avendo
+ superato il limite sul numero di file aperti nel sistema.
+ \item[\errcode{ENODEV}] \param{dev} non corrisponde ad un \textit{mount
+ point} attivo.
+ \item[\errcode{ENOPKG}] il kernel è stato compilato senza supporto per le
+ quote.
+ \item[\errcode{ENOTBLK}] \param{dev} non è un dispositivo a blocchi.
+ \item[\errcode{EPERM}] non si hanno i permessi per l'operazione richiesta.
+ \item[\errcode{ESRCH}] è stato richiesto uno fra \const{Q\_GETQUOTA},
+ \const{Q\_SETQUOTA}, \const{Q\_SETUSE}, \const{Q\_SETQLIM} per un
+ filesystem senza quote attivate.
+ \end{errlist}
+}
+\end{funcproto}
+
+% TODO rivedere gli errori
+
+La funzione richiede che il filesystem sul quale si vuole operare, che deve
+essere specificato con il nome del relativo file di dispositivo nell'argomento
+\param{dev}, sia montato con il supporto delle quote abilitato. Per le
+operazioni che lo richiedono inoltre si dovrà indicare con l'argomento
+\param{id} l'utente o il gruppo o il progetto (specificati rispettivamente per
+\ids{UID}, \ids{GID} o identificativo) su cui si vuole operare,\footnote{nel
+ caso di \textit{project quota} gli identificativi vengono associati alla
+ directory base del progetto nel file \file{/etc/projects}, ed impostati con
+ \cmd{xfs\_quota}, l'argomento è di natura sistemistica e va al di là dello
+ scopo di questo testo.} o altri dati relativi all'operazione. Alcune
+operazioni più complesse usano infine l'argomento \param{addr} per indicare un
+indirizzo ad un area di memoria il cui utilizzo dipende dall'operazione
+stessa.
+
+La funzione prevede la possibilità di eseguire una serie operazioni sulle
+quote molto diverse fra loro, la scelta viene effettuata tramite il primo
+argomento, \param{cmd}, che però oltre all'operazione indica anche a quale
+tipo di quota (utente o gruppo) l'operazione deve applicarsi. Per questo il
+valore di questo argomento viene costruito con l'ausilio della di una apposita
+macro \macro{QCMD}:
+
+{\centering
+\vspace{3pt}
+\begin{funcbox}{
+\fhead{sys/quota.h}
+\fdecl{int \macrod{QCMD}(subcmd,type)}
+\fdesc{Imposta il comando \param{subcmd} per il tipo di quote (utente o
+ gruppo) \param{type}.}
+}
+\end{funcbox}
+}
+
+La macro consente di specificare, oltre al tipo di operazione, da indicare con
+l'argomento \param{subcmd}, se questa deve applicarsi alle quote utente o alle
+quote gruppo o alle quote progetto. Questo viene indicato dall'argomento
+\param{type} che deve essere sempre definito ed assegnato ad uno fra i valori
+\const{USRQUOTA}, \const{GRPQUOTA} e \const{PRJQUOTA}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}{|l|p{10cm}|}
+ \hline
+ \textbf{Comando} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \constd{Q\_QUOTAON} & Attiva l'applicazione delle quote disco per il
+ filesystem indicato da \param{dev}, si deve passare
+ in \param{addr} il \textit{pathname} al file che
+ mantiene le quote, che deve esistere, e \param{id}
+ deve indicare la versione del formato con uno dei
+ valori di tab.~\ref{tab:quotactl_id_format};
+ l'operazione richiede i privilegi di
+ amministratore.\\
+ \constd{Q\_QUOTAOFF}& Disattiva l'applicazione delle quote disco per il
+ filesystem indicato da \param{dev}, \param{id}
+ e \param{addr} vengono ignorati; l'operazione
+ richiede i privilegi di amministratore.\\
+ \constd{Q\_GETQUOTA}& Legge i limiti ed i valori correnti delle quote nel
+ filesystem indicato da \param{dev} per l'utente o
+ il gruppo specificato da \param{id}; si devono avere
+ i privilegi di amministratore per leggere i dati
+ relativi ad altri utenti o a gruppi di cui non si fa
+ parte, il risultato viene restituito in una struttura
+ \struct{dqblk} all'indirizzo indicato
+ da \param{addr}.\\
+ \constd{Q\_SETQUOTA}& Imposta i limiti per le quote nel filesystem
+ indicato da \param{dev} per l'utente o il gruppo
+ specificato da \param{id} secondo i valori ottenuti
+ dalla struttura \struct{dqblk} puntata
+ da \param{addr}; l'operazione richiede i privilegi
+ di amministratore.\\
+ \constd{Q\_GETINFO} & Legge le informazioni (in sostanza i \textit{grace
+ time}) delle quote del filesystem indicato
+ da \param{dev} sulla struttura \struct{dqinfo}
+ puntata da \param{addr}, \param{id} viene ignorato.\\
+ \constd{Q\_SETINFO} & Imposta le informazioni delle quote del filesystem
+ indicato da \param{dev} come ottenuti dalla
+ struttura \struct{dqinfo} puntata
+ da \param{addr}, \param{id} viene ignorato;
+ l'operazione richiede i privilegi di amministratore.\\
+ \constd{Q\_GETFMT} & Richiede il valore identificativo (quello di
+ tab.~\ref{tab:quotactl_id_format}) per il formato
+ delle quote attualmente in uso sul filesystem
+ indicato da \param{dev}, che sarà memorizzato
+ sul buffer di 4 byte puntato da \param{addr}.\\
+ \constd{Q\_SYNC} & Aggiorna la copia su disco dei dati delle quote del
+ filesystem indicato da \param{dev}; in questo
+ caso \param{dev} può anche essere \val{NULL} nel
+ qual caso verranno aggiornati i dati per tutti i
+ filesystem con quote attive, \param{id}
+ e \param{addr} vengono comunque ignorati.\\
+ \constd{Q\_GETSTATS}& Ottiene statistiche ed altre informazioni generali
+ relative al sistema delle quote per il filesystem
+ indicato da \param{dev}, richiede che si
+ passi come argomento \param{addr} l'indirizzo di una
+ struttura \struct{dqstats}, mentre i valori
+ di \param{id} e \param{dev} vengono ignorati;
+ l'operazione è obsoleta e non supportata nei kernel
+ più recenti, che espongono la stessa informazione
+ nei file sotto \procfile{/proc/self/fs/quota/}.\\
+% \const{} & .\\
+ \hline
+ \end{tabular}
+ \caption{Possibili valori per l'argomento \param{subcmd} di
+ \macro{QCMD}.}
+ \label{tab:quotactl_commands}
+\end{table}
+
+I possibili valori per l'argomento \param{subcmd} di \macro{QCMD} sono
+riportati in tab.~\ref{tab:quotactl_commands}, che illustra brevemente il
+significato delle operazioni associate a ciascuno di essi. In generale le
+operazioni di attivazione, disattivazione e di modifica dei limiti delle quote
+sono riservate e richiedono i privilegi di amministratore.\footnote{per essere
+ precisi tutte le operazioni indicate come privilegiate in
+ tab.~\ref{tab:quotactl_commands} richiedono la capacità
+ \const{CAP\_SYS\_ADMIN}.} Inoltre gli utenti possono soltanto richiedere i
+dati relativi alle proprie quote, solo l'amministratore può ottenere i dati di
+tutti.
+
+
+Alcune delle operazioni di tab.~\ref{tab:quotactl_commands} sono alquanto
+complesse e richiedono un approfondimento maggiore. Le due più rilevanti sono
+probabilmente \const{Q\_GETQUOTA} e \const{Q\_SETQUOTA}, che consentono la
+gestione dei limiti delle quote. Entrambe fanno riferimento ad una specifica
+struttura \struct{dqblk}, la cui definizione è riportata in
+fig.~\ref{fig:dqblk_struct},\footnote{la definizione mostrata è quella usata
+ fino dal kernel 2.4.22, non prenderemo in considerazione le versioni
+ obsolete.} nella quale vengono inseriti i dati relativi alle quote di un
+singolo utente o gruppo.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.95\textwidth}
+ \includestruct{listati/dqblk.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{dqblk} per i dati delle quote disco.}
+ \label{fig:dqblk_struct}
+\end{figure}
+
+La struttura \struct{dqblk} viene usata sia con \const{Q\_GETQUOTA} per
+ottenere i valori correnti dei limiti e dell'occupazione delle risorse, che
+con \const{Q\_SETQUOTA} per effettuare modifiche ai limiti. Come si può notare
+ci sono alcuni campi (in sostanza \val{dqb\_curspace}, \val{dqb\_curinodes},
+\val{dqb\_btime}, \val{dqb\_itime}) che hanno senso solo in lettura, in quanto
+riportano uno stato non modificabile da \func{quotactl} come l'uso corrente di
+spazio disco ed \textit{inode}, o il tempo che resta nel caso si sia superato
+un \textit{soft limit}.
+
+Inoltre in caso di modifica di un limite si può voler operare solo su una
+delle risorse (blocchi o \textit{inode}),\footnote{non è possibile modificare
+ soltanto uno dei limiti (\textit{hard} o \textit{soft}) occorre sempre
+ rispecificarli entrambi.} per questo la struttura prevede un campo apposito,
+\val{dqb\_valid}, il cui scopo è quello di indicare quali sono gli altri campi
+che devono essere considerati validi. Questo campo è una maschera binaria che
+deve essere espressa nei termini di OR aritmetico delle apposite costanti di
+tab.~\ref{tab:quotactl_qif_const}, dove si è riportato il significato di
+ciascuna di esse ed i campi a cui fanno riferimento.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}{|l|p{10cm}|}
+ \hline
+ \textbf{Costante} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \constd{QIF\_BLIMITS}& Limiti sui blocchi di spazio disco
+ (\val{dqb\_bhardlimit} e \val{dqb\_bsoftlimit}).\\
+ \constd{QIF\_SPACE} & Uso corrente dello spazio disco
+ (\val{dqb\_curspace}).\\
+ \constd{QIF\_ILIMITS}& Limiti sugli \textit{inode}
+ (\val{dqb\_ihardlimit} e \val{dqb\_isoftlimit}).\\
+ \constd{QIF\_INODES} & Uso corrente degli \textit{inode}
+ (\val{dqb\_curinodes}).\\
+ \constd{QIF\_BTIME} & Tempo di sforamento del \textit{soft limit} sul
+ numero di blocchi (\val{dqb\_btime}).\\
+ \constd{QIF\_ITIME} & Tempo di sforamento del \textit{soft limit} sul
+ numero di \textit{inode} (\val{dqb\_itime}).\\
+ \constd{QIF\_LIMITS} & L'insieme di \const{QIF\_BLIMITS} e
+ \const{QIF\_ILIMITS}.\\
+ \constd{QIF\_USAGE} & L'insieme di \const{QIF\_SPACE} e
+ \const{QIF\_INODES}.\\
+ \constd{QIF\_TIMES} & L'insieme di \const{QIF\_BTIME} e
+ \const{QIF\_ITIME}.\\
+ \constd{QIF\_ALL} & Tutti i precedenti.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti per il campo \val{dqb\_valid} di \struct{dqblk}.}
+ \label{tab:quotactl_qif_const}
+\end{table}
+
+In lettura con \const{Q\_SETQUOTA} eventuali valori presenti in \struct{dqblk}
+vengono comunque ignorati, al momento la funzione sovrascrive tutti i campi
+che restituisce e li marca come validi in \val{dqb\_valid}. Si possono invece
+usare \const{QIF\_BLIMITS} o \const{QIF\_ILIMITS} per richiedere di impostare
+solo la rispettiva tipologia di limiti con \const{Q\_SETQUOTA}. Si tenga
+presente che il sistema delle quote richiede che l'occupazione di spazio disco
+sia indicata in termini di blocchi e non di byte, dato che la dimensione dei
+blocchi dipende da come si è creato il filesystem potrà essere necessario
+effettuare qualche conversione per avere un valore in byte.\footnote{in genere
+ viene usato un default di 1024 byte per blocco, ma quando si hanno file di
+ dimensioni medie maggiori può convenire usare valori più alti per ottenere
+ prestazioni migliori in conseguenza di un minore frazionamento dei dati e di
+ indici più corti.}
+
+Come accennato la realizzazione delle quote disco ha visto diverse revisioni,
+con modifiche sia del formato delle stesse che dei nomi dei file
+utilizzati. Per questo alcune operazioni di gestione (in particolare
+\const{Q\_QUOTAON} e \const{Q\_GETFMT}) e possono fare riferimento a queste
+versioni, che vengono identificate tramite le costanti di
+tab.~\ref{tab:quotactl_id_format}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}{|l|p{10cm}|}
+ \hline
+ \textbf{Identificatore} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \constd{QFMT\_VFS\_OLD}& Il vecchio (ed obsoleto) formato delle quote.\\
+ \constd{QFMT\_VFS\_V0} & La versione 0 usata dal VFS di Linux, supporta
+ \ids{UID} e \ids{GID} a 32 bit e limiti fino a
+ $2^{42}$ byte e $2^{32}$ file.\\
+ \constd{QFMT\_VFS\_V1} & La versione 1 usata dal VFS di Linux, supporta
+ \ids{UID} e \ids{GID} a 32 bit e limiti fino a
+ $2^{64}$ byte e $2^{64}$ file.\\
+ \hline
+ \end{tabular}
+ \caption{Valori di identificazione del formato delle quote.}
+ \label{tab:quotactl_id_format}
+\end{table}
+
+Altre due operazioni che necessitano di ulteriori spiegazioni sono
+\const{Q\_GETINFO} e \const{Q\_SETINFO}, che consentono di ottenere i dati
+relativi alle impostazioni delle altre proprietà delle quote, che al momento
+sono solo la durata del \textit{grace time} per i due tipi di limiti. Queste
+sono due proprietà generali identiche per tutti gli utenti (e i gruppi), per
+cui viene usata una operazione distinta dalle precedenti. Anche in questo caso
+le due operazioni richiedono l'uso di una apposita struttura \struct{dqinfo},
+la cui definizione è riportata in fig.~\ref{fig:dqinfo_struct}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.8\textwidth}
+ \includestruct{listati/dqinfo.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{dqinfo} per i dati delle quote disco.}
+ \label{fig:dqinfo_struct}
+\end{figure}
+
+Come per \struct{dqblk} anche in questo caso viene usato un campo della
+struttura, \val{dqi\_valid} come maschera binaria per dichiarare quale degli
+altri campi sono validi; le costanti usate per comporre questo valore sono
+riportate in tab.~\ref{tab:quotactl_iif_const} dove si è riportato il
+significato di ciascuna di esse ed i campi a cui fanno riferimento.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}{|l|l|}
+ \hline
+ \textbf{Costante} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \constd{IIF\_BGRACE}& Il \textit{grace period} per i blocchi
+ (\val{dqi\_bgrace}).\\
+ \constd{IIF\_IGRACE}& Il \textit{grace period} per gli \textit{inode}
+ (\val{dqi\_igrace}).\\
+ \constd{IIF\_FLAGS} & I flag delle quote (\val{dqi\_flags}) (inusato ?).\\
+ \constd{IIF\_ALL} & Tutti i precedenti.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti per il campo \val{dqi\_valid} di \struct{dqinfo}.}
+ \label{tab:quotactl_iif_const}
+\end{table}
+
+Come in precedenza con \const{Q\_GETINFO} tutti i valori vengono letti
+sovrascrivendo il contenuto di \struct{dqinfo} e marcati come validi in
+\val{dqi\_valid}. In scrittura con \const{Q\_SETINFO} si può scegliere quali
+impostare, si tenga presente che i tempi dei campi \val{dqi\_bgrace} e
+\val{dqi\_igrace} devono essere specificati in secondi.
+
+Come esempi dell'uso di \func{quotactl} utilizzeremo estratti del codice di un
+modulo Python usato per fornire una interfaccia diretta a \func{quotactl}
+senza dover passare dalla scansione dei risultati di un comando. Il modulo si
+trova fra i pacchetti Debian messi a disposizione da Truelite Srl,
+all'indirizzo \url{http://labs.truelite.it/projects/packages}.\footnote{in
+ particolare il codice C del modulo è nel file \texttt{quotamodule.c}
+ visionabile a partire dall'indirizzo indicato nella sezione
+ \textit{Repository}.}
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/get_quota.c}
+ \end{minipage}
+ \caption{Esempio di codice per ottenere i dati delle quote.}
+ \label{fig:get_quota}
+\end{figure}
+
+Il primo esempio, riportato in fig.~\ref{fig:get_quota}, riporta il codice
+della funzione che consente di leggere le quote. La funzione fa uso
+dell'interfaccia dal C verso Python, che definisce i vari simboli \texttt{Py*}
+(tipi di dato e funzioni). Non staremo ad approfondire i dettagli di questa
+interfaccia, per la quale esistono numerose trattazioni dettagliate, ci
+interessa solo esaminare l'uso di \func{quotactl}.
+
+In questo caso la funzione prende come argomenti (\texttt{\small 1}) l'intero
+\texttt{who} che indica se si vuole operare sulle quote utente o gruppo,
+l'identificatore \texttt{id} dell'utente o del gruppo scelto, ed il nome del
+file di dispositivo del filesystem su cui si sono attivate le
+quote.\footnote{questi vengono passati come argomenti dalle funzioni mappate
+ come interfaccia pubblica del modulo (una per gruppi ed una per gli utenti)
+ che si incaricano di decodificare i dati passati da una chiamata nel codice
+ Python.} Questi argomenti vengono passati direttamente alla chiamata a
+\func{quotactl} (\texttt{\small 5}), a parte \texttt{who} che viene abbinato
+con \macro{QCMD} al comando \const{Q\_GETQUOTA} per ottenere i dati.
+
+La funzione viene eseguita all'interno di un condizionale (\texttt{\small
+ 5-16}) che in caso di successo provvede a costruire (\texttt{\small 6-12})
+opportunamente una risposta restituendo tramite la opportuna funzione di
+interfaccia un oggetto Python contenente i dati della struttura \struct{dqblk}
+relativi a uso corrente e limiti sia per i blocchi che per gli
+\textit{inode}. In caso di errore (\texttt{\small 13-15}) si usa un'altra
+funzione dell'interfaccia per passare il valore di \var{errno} come eccezione.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/set_block_quota.c}
+ \end{minipage}
+ \caption{Esempio di codice per impostare i limiti sullo spazio disco.}
+ \label{fig:set_block_quota}
+\end{figure}
+
+Per impostare i limiti sullo spazio disco si potrà usare una seconda funzione,
+riportata in fig.~\ref{fig:set_block_quota}, che prende gli stessi argomenti
+della precedente, con lo stesso significato, a cui si aggiungono i valori per
+il \textit{soft limit} e l'\textit{hard limit}. In questo caso occorrerà,
+prima di chiamare \func{quotactl}, inizializzare opportunamente
+(\texttt{\small 5-7}) i campi della struttura \struct{dqblk} che si vogliono
+utilizzare (quelli relativi ai limiti sui blocchi) e specificare gli stessi
+con \const{QIF\_BLIMITS} in \var{dq.dqb\_valid}.
+
+Fatto questo la chiamata a \func{quotactl}, stavolta con il comando
+\const{Q\_SETQUOTA}, viene eseguita come in precedenza all'interno di un
+condizionale (\texttt{\small 9-14}). In questo caso non essendovi da
+restituire nessun dato in caso di successo si usa (\texttt{\small 10}) una
+apposita funzione di uscita, mentre si restituisce come prima una eccezione
+con il valore di \var{errno} in caso di errore (\texttt{\small 12-13}).
+
+\subsection{La gestione dei {chroot}}
+\label{sec:file_chroot}
+
+% TODO: valutare se introdurre una nuova sezione sulle funzionalità di
+% sicurezza avanzate, con dentro chroot SELinux e AppArmor, Tomoyo, Smack,
+% cgroup o altro
+
+% TODO: spostare chroot e le funzioni affini relative ai container da qualche
+% parte diversa se è il caso.
+
+% TODO Inheriting capabilities vedi http://lwn.net/Articles/632520/ eambient
+% capabilities introdotte con il kernel 4.3, vedi
+% http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=58319057b7847667f0c9585b9de0e8932b0fdb08
+
+Benché non abbia niente a che fare con permessi, utenti e gruppi, la funzione
+\func{chroot} viene usata spesso per restringere le capacità di accesso di un
+programma ad una sezione limitata del filesystem, per cui ne parleremo in
+questa sezione.
+
+Come accennato in sez.~\ref{sec:proc_fork} ogni processo oltre ad una
+directory di lavoro, ha anche una directory \textsl{radice}\footnote{entrambe
+ sono contenute in due campi (rispettivamente \var{pwd} e \var{root}) di
+ \kstruct{fs\_struct}; vedi fig.~\ref{fig:proc_task_struct}.} che, pur
+essendo di norma corrispondente alla radice dell'albero dei file dell'intero
+sistema, ha per il processo il significato specifico di directory rispetto
+alla quale vengono risolti i \textit{pathname} assoluti.\footnote{cioè quando
+ un processo chiede la risoluzione di un \textit{pathname}, il kernel usa
+ sempre questa directory come punto di partenza.} Il fatto che questo valore
+sia specificato per ogni processo apre allora la possibilità di modificare le
+modalità di risoluzione dei \textit{pathname} assoluti da parte di un processo
+cambiando questa directory, così come si fa coi \textit{pathname} relativi
+cambiando la directory di lavoro.
+
+Normalmente la directory radice di un processo coincide con la radice generica
+dell'albero dei file, che è la directory che viene montata direttamente dal
+kernel all'avvio secondo quanto illustrato in sez.~\ref{sec:file_pathname}.
+Questo avviene perché, come visto in sez.~\ref{cha:process_handling} la
+directory radice di un processo viene ereditata dal padre attraverso una
+\func{fork} e mantenuta attraverso una \func{exec}, e siccome tutti i processi
+derivano da \cmd{init}, che ha come radice quella montata dal kernel, questa
+verrà mantenuta.
+
+In certe situazioni però è utile poter impedire che un processo possa accedere
+a tutto l'albero dei file iniziale; per far questo si può cambiare la sua
+directory radice con la funzione di sistema \funcd{chroot}, il cui prototipo
+è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int chroot(const char *path)}
+\fdesc{Cambia la directory radice del processo.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EPERM}] non si hanno i privilegi di amministratore.
+ \end{errlist}
+ ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{ENOMEM}, \errval{ENOTDIR}, \errval{EACCES}, \errval{ELOOP};
+ \errval{EROFS} e \errval{EIO} nel loro significato generico.}
+\end{funcproto}
+
+La funzione imposta la directory radice del processo a quella specificata da
+\param{path} (che ovviamente deve esistere) ed ogni \textit{pathname} assoluto
+usato dalle funzioni chiamate nel processo sarà risolto a partire da essa,
+rendendo impossibile accedere alla parte di albero sovrastante. Si ha così
+quella che viene chiamata una \textit{chroot jail}, in quanto il processo non
+può più accedere a file al di fuori della sezione di albero in cui è stato
+\textsl{imprigionato}.
+
+Solo un processo con i privilegi di amministratore può usare questa
+funzione,\footnote{più precisamente se possiede la capacità
+ \const{CAP\_SYS\_CHROOT}.} e la nuova radice, per quanto detto in
+sez.~\ref{sec:proc_fork}, sarà ereditata da tutti i suoi processi figli. Si
+tenga presente però che la funzione non cambia la directory di lavoro del
+processo, che potrebbe restare fuori dalla \textit{chroot jail}.
+
+Questo è il motivo per cui la funzione è efficace nel restringere un processo
+ad un ramo di albero solo se dopo averla eseguita si cedono i privilegi di
+amministratore. Infatti se per un qualunque motivo il processo resta con la
+sua directory di lavoro al di fuori dalla \textit{chroot jail}, potrà accedere
+a tutto il resto del filesystem usando dei \textit{pathname} relativi, dato
+che in tal caso è possibile, grazie all'uso di ``\texttt{..}'', risalire
+all'indietro fino alla radice effettiva dell'albero dei file.