Documentati O_PATH (fine) e O_NOFOLLOW
[gapil.git] / fileio.tex
index 601d98bd10f99df4e7c8bad8536a9878420764ae..dc5bdfa2d45b291a0e6ff3304af097350b9a5f30 100644 (file)
@@ -1,6 +1,6 @@
 %% fileio.tex (merge fileunix.tex - filestd.tex)
 %%
-%% Copyright (C) 2000-2012 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2018 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
 \chapter{La gestione dell'I/O su file}
 \label{cha:file_IO_interface}
 
-
 Esamineremo in questo capitolo le due interfacce di programmazione che
 consentono di gestire i dati mantenuti nei file. Cominceremo con quella nativa
-del sistema, detta dei \itindex{file~descriptor} \textit{file descriptor}, che
-viene fornita direttamente dalle \textit{system call} e che non prevede
-funzionalità evolute come la bufferizzazione o funzioni di lettura o scrittura
+del sistema, detta dei \textit{file descriptor}, che viene fornita
+direttamente dalle \textit{system call} e che non prevede funzionalità evolute
+come la bufferizzazione o funzioni di lettura o scrittura
 formattata. Esamineremo poi anche l'interfaccia definita dallo standard ANSI
 C, che viene chiamata dei \textit{file stream} o anche più brevemente degli
 \textit{stream}. Per entrambe dopo una introduzione alle caratteristiche
@@ -30,13 +29,13 @@ ultime le caratteristiche più avanzate.
 
 
 Come visto in sez.~\ref{sec:file_vfs_work} il kernel mette a disposizione
-tramite il \itindex{Virtual~File~System} \textit{Virtual File System} una
-serie di \textit{system call} che consentono di operare sui file in maniera
-generale. Abbiamo trattato quelle relative alla gestione delle proprietà dei
-file nel precedente capitolo, vedremo quelle che si applicano al contenuto dei
-file in questa sezione, iniziando con una breve introduzione sull'architettura
-dei \textit{file descriptor} per poi trattare le funzioni di base e le
-modalità con cui consentono di gestire i dati memorizzati sui file.
+tramite il \textit{Virtual File System} una serie di \textit{system call} che
+consentono di operare sui file in maniera generale. Abbiamo trattato quelle
+relative alla gestione delle proprietà dei file nel precedente capitolo,
+vedremo quelle che si applicano al contenuto dei file in questa sezione,
+iniziando con una breve introduzione sull'architettura dei \textit{file
+  descriptor} per poi trattare le funzioni di base e le modalità con cui
+consentono di gestire i dati memorizzati sui file.
 
 
 \subsection{I \textit{file descriptor}}
@@ -51,56 +50,56 @@ chiamata l'interfaccia dei \textit{file descriptor}.
 
 Per poter accedere al contenuto di un file occorre creare un canale di
 comunicazione con il kernel che renda possibile operare su di esso. Questo si
-fa aprendo il file con la funzione \func{open} (vedi sez.~\ref{sec:file_open})
-che provvederà a localizzare \itindex{inode} l'inode del file e inizializzare
-i puntatori che rendono disponibili le funzioni che il
-\itindex{Virtual~File~System} VFS mette a disposizione (quelle di
-tab.~\ref{tab:file_file_operations}). Una volta terminate le operazioni, il
+fa aprendo il file con la funzione \func{open} (vedi
+sez.~\ref{sec:file_open_close}) che provvederà a localizzare l'\textit{inode}
+del file e inizializzare i puntatori che rendono disponibili le funzioni che
+il VFS mette a disposizione (quelle di
+tab.~\ref{tab:file_file_operations}). Una volta terminate le operazioni, il 
 file dovrà essere chiuso, e questo chiuderà il canale di comunicazione
 impedendo ogni ulteriore operazione.
 
 All'interno di ogni processo i file aperti sono identificati da un numero
-intero non negativo, che viene chiamato \textit{file descriptor}.  Quando un
-file viene aperto la funzione \func{open} restituisce questo numero, tutte le
-ulteriori operazioni dovranno essere compiute specificando questo stesso
-numero come argomento alle varie funzioni dell'interfaccia.
+intero non negativo, che viene chiamato appunto \textit{file descriptor}.
+Quando un file viene aperto la funzione \func{open} restituisce questo numero,
+tutte le ulteriori operazioni dovranno essere compiute specificando questo
+stesso numero come argomento alle varie funzioni dell'interfaccia.
+
+\itindbeg{process~table}
+\itindbeg{file~table}
 
 Per capire come funziona il meccanismo occorre spiegare a grandi linee come il
 kernel gestisce l'interazione fra processi e file.  Abbiamo già accennato in
 sez.~\ref{sec:proc_hierarchy} come il kernel mantenga un elenco di tutti
-processi nella cosiddetta \itindex{process~table} \textit{process table}. Lo
-stesso, come accennato in sez.~\ref{sec:file_vfs_work}, vale anche per tutti i
-file aperti, il cui elenco viene mantenuto nella cosiddetta
-\itindex{file~table} \textit{file table}.
-
-La \itindex{process~table} \textit{process table} è una tabella che contiene
-una voce per ciascun processo attivo nel sistema. Ciascuna voce è costituita
-dal puntatore a una struttura di tipo \kstruct{task\_struct} nella quale sono
-raccolte tutte le informazioni relative al processo, fra queste informazioni
-c'è anche il puntatore ad una ulteriore struttura di tipo
+processi nella cosiddetta \textit{process table}. Lo stesso, come accennato in
+sez.~\ref{sec:file_vfs_work}, vale anche per tutti i file aperti, il cui
+elenco viene mantenuto nella cosiddetta \textit{file table}.
+
+La \textit{process table} è una tabella che contiene una voce per ciascun
+processo attivo nel sistema. Ciascuna voce è costituita dal puntatore a una
+struttura di tipo \kstruct{task\_struct} nella quale sono raccolte tutte le
+informazioni relative al processo, fra queste informazioni c'è anche il
+puntatore ad una ulteriore struttura di tipo
 \kstruct{files\_struct},\footnote{la definizione corrente di questa struttura
   si trova nel file \texttt{include/linux/fdtable.h} dei sorgenti del kernel,
   quella mostrata in fig.~\ref{fig:file_proc_file} è una versione pesantemente
   semplificata.} che contiene le informazioni relative ai file che il processo
 ha aperto.
 
-La \itindex{file~table} \textit{file table} è una tabella che contiene una
-voce per ciascun file che è stato aperto nel sistema. Come accennato in
-sez.~\ref{sec:file_vfs_work} per ogni file aperto viene allocata una struttura
-\kstruct{file} e la \textit{file table} è costituita da un elenco di puntatori
-a ciascuna di queste strutture, che, come illustrato in
-fig.~\ref{fig:kstruct_file}, contengono le informazioni necessarie per la
-gestione dei file, ed in particolare:
+La \textit{file table} è una tabella che contiene una voce per ciascun file
+che è stato aperto nel sistema. Come accennato in sez.~\ref{sec:file_vfs_work}
+per ogni file aperto viene allocata una struttura \kstruct{file} e la
+\textit{file table} è costituita da un elenco di puntatori a ciascuna di
+queste strutture, che, come illustrato in fig.~\ref{fig:kstruct_file},
+contengono le informazioni necessarie per la gestione dei file, ed in
+particolare:
 \begin{itemize*}
-\item i flag di stato \itindex{file~status~flag} del file nel campo
-  \var{f\_flags}.
+\item i flag di stato del file nel campo \var{f\_flags}.
 \item la posizione corrente nel file, il cosiddetto \textit{offset}, nel campo
   \var{f\_pos}.
 \item un puntatore alla struttura \kstruct{inode} che identifica
-  \itindex{inode} l'\textit{inode} del file.\footnote{nel kernel 2.4.x si è in
-    realtà passati ad un puntatore ad una struttura \kstruct{dentry} che punta
-    a sua volta \itindex{inode} all'\textit{inode} passando per la nuova
-    struttura del VFS.}
+  l'\textit{inode} del file.\footnote{nel kernel 2.4.x si è in realtà passati
+    ad un puntatore ad una struttura \kstruct{dentry} che punta a sua volta
+    all'\textit{inode} passando per la nuova struttura del VFS.}
 \item un puntatore \var{f\_op} alla tabella delle funzioni che si possono
   usare sul file.\footnote{quelle della struttura \kstruct{file\_operation},
     descritte sommariamente in tab.~\ref{tab:file_file_operations}.}
@@ -110,15 +109,17 @@ gestione dei file, ed in particolare:
   \centering
   \includegraphics[width=12cm]{img/procfile}
   \caption{Schema della architettura dell'accesso ai file attraverso
-  l'interfaccia dei \textit{file descriptor}.}
+  l'interfaccia dei file descriptor.}
   \label{fig:file_proc_file}
 \end{figure}
 
 In fig.~\ref{fig:file_proc_file} si è riportato uno schema semplificato in cui
 è illustrata questa architettura, ed in cui si sono evidenziate le
-interrelazioni fra la \itindex{file~table} \textit{file table}, la
-\itindex{process~table} \textit{process table} e le varie strutture di dati
-che il kernel mantiene per ciascun file e ciascun processo.
+interrelazioni fra la \textit{file table}, la \textit{process table} e le
+varie strutture di dati che il kernel mantiene per ciascun file e ciascun
+processo.
+
+\itindend{process~table}
 
 Come si può notare alla fine il collegamento che consente di porre in
 relazione i file ed i processi è effettuato attraverso i dati mantenuti nella
@@ -127,37 +128,42 @@ essenziali come:
 \begin{itemize*}
 \item i flag relativi ai file aperti dal processo.
 \item il numero di file aperti dal processo.
-\item una tabella di puntatori alla relativa voce nella \itindex{file~table}
-  \textit{file table} per ciascun file aperto.
+\item la \itindex{file~descriptor~table} \textit{file descriptor table}, una
+  tabella con i puntatori, per ciascun file aperto, alla relativa voce nella
+  \textit{file table}.
 \end{itemize*}
 
-In questa infrastruttura un \textit{file descriptor} non è altro che l'intero
-positivo che indicizza quest'ultima tabella, e che consente di recuperare il
-puntatore alla struttura \kstruct{file} corrispondente al file aperto dal
-processo a cui era stato assegnato questo indice. Una volta ottenuta grazie
-al \textit{file descriptor} la struttura \kstruct{file} corrispondente al file
-voluto nella \itindex{file~table} \textit{file table}, il kernel potrà usare
-le funzioni messe disposizione dal VFS per eseguire sul file tutte le
-operazioni necessarie.
+In questa infrastruttura un file descriptor non è altro che l'intero positivo
+che indicizza quest'ultima tabella, e che consente di recuperare il puntatore
+alla struttura \kstruct{file} corrispondente al file aperto dal processo a cui
+era stato assegnato questo indice. Una volta ottenuta grazie al file
+descriptor la struttura \kstruct{file} corrispondente al file voluto nella
+\textit{file table}, il kernel potrà usare le funzioni messe disposizione dal
+VFS per eseguire sul file tutte le operazioni necessarie.
 
 Il meccanismo dell'apertura dei file prevede che venga sempre fornito il primo
-\textit{file descriptor} libero nella tabella, e per questo motivo essi
-vengono assegnati in successione tutte le volte che si apre un nuovo file,
-posto che non ne sia stato chiuso nessuno in precedenza.
+file descriptor libero nella tabella, e per questo motivo essi vengono
+assegnati in successione tutte le volte che si apre un nuovo file, posto che
+non ne sia stato chiuso nessuno in precedenza.
+
+\itindbeg{standard~input} 
+\itindbeg{standard~output}
+\itindbeg{standard~error}
 
 In tutti i sistemi unix-like esiste una convenzione generale per cui ogni
 processo si aspetta di avere sempre tre file aperti che, per quanto appena
-detto, avranno come \itindex{file~descriptor} \textit{file descriptor} i
-valori 0, 1 e 2.  Il primo file è sempre associato al cosiddetto
-\itindex{standard~input} \textit{standard input}, è cioè il file da cui un
-processo si aspetta di dover leggere i dati in ingresso. Il secondo file è il
-cosiddetto \itindex{standard~output} \textit{standard output}, cioè quello su
-cui ci si aspetta di dover scrivere i dati in uscita. Il terzo è lo
-\itindex{standard~error} \textit{standard error}, su cui vengono scritti i
-dati relativi agli errori.
-
-Benché questa sia soltanto una convenzione, essa è seguita dalla gran parte
-delle applicazioni, e non aderirvi potrebbe portare a problemi di
+detto, avranno come \textit{file descriptor} i valori 0, 1 e 2.  Il primo file
+è sempre associato al cosiddetto \textit{standard input}, è cioè il file da
+cui un processo si aspetta di dover leggere i dati in ingresso. Il secondo
+file è il cosiddetto \textit{standard output}, cioè quello su cui ci si
+aspetta di dover scrivere i dati in uscita. Il terzo è lo \textit{standard
+  error}, su cui vengono scritti i dati relativi agli errori.
+
+\itindend{file~descriptor} 
+
+
+Benché questa sia alla fine soltanto una convenzione, essa è seguita dalla
+totalità delle applicazioni, e non aderirvi potrebbe portare a problemi di
 interoperabilità.  Nel caso della shell tutti questi file sono associati al
 terminale di controllo, e corrispondono quindi alla lettura della tastiera per
 l'ingresso e alla scrittura sul terminale per l'uscita.  Lo standard POSIX.1
@@ -172,39 +178,37 @@ tab.~\ref{tab:file_std_files}.
     \textbf{File} & \textbf{Significato} \\
     \hline
     \hline
-    \const{STDIN\_FILENO}  & \textit{file descriptor} dello \textit{standard
-      input} \\
-    \const{STDOUT\_FILENO} & \textit{file descriptor} dello \textit{standard
-      output} \\
-    \const{STDERR\_FILENO} & \textit{file descriptor} dello \textit{standard
-      error}\\
+    \constd{STDIN\_FILENO}  & file descriptor dello \textit{standard input}.\\ 
+    \constd{STDOUT\_FILENO} & file descriptor dello \textit{standard output}.\\
+    \constd{STDERR\_FILENO} & file descriptor dello \textit{standard error}.\\
     \hline
   \end{tabular}
   \caption{Costanti definite in \headfile{unistd.h} per i file standard.}
   \label{tab:file_std_files}
 \end{table}
 
+\itindend{standard~input} 
+\itindend{standard~output}
+\itindend{standard~error}
+
 In fig.~\ref{fig:file_proc_file} si è rappresentata una situazione diversa
 rispetto a quella usuale della shell, in cui tutti e tre questi file fanno
 riferimento al terminale su cui si opera. Nell'esempio invece viene illustrata
-la situazione di un programma in cui lo \itindex{standard~input}
-\textit{standard input} è associato ad un file mentre lo
-\itindex{standard~output} \textit{standard output} e lo
-\itindex{standard~error} \textit{standard error} sono associati ad un altro
-file.  Si noti poi come per questi ultimi le strutture \kstruct{file} nella
-\itindex{file~table} \textit{file table}, pur essendo distinte, fanno
-riferimento allo stesso \itindex{inode} \textit{inode}, dato che il file che è
-stato aperto lo stesso. Questo è quello che avviene normalmente quando si apre
-più volte lo stesso file.
-
-Si ritrova quindi anche con le voci della \itindex{file~table} \textit{file
-  table} una situazione analoga di quella delle voci di una directory, con la
-possibilità di avere più voci che fanno riferimento allo stesso
-\itindex{inode} \textit{inode}. L'analogia è in realtà molto stretta perché
-quando si cancella un file, il kernel verifica anche che non resti nessun
-riferimento in una una qualunque voce della \itindex{file~table} \textit{file
-  table} prima di liberare le risorse ad esso associate e disallocare il
-relativo \itindex{inode} \textit{inode}.
+la situazione di un programma in cui lo \textit{standard input} è associato ad
+un file mentre lo \textit{standard output} e lo \textit{standard error} sono
+associati ad un altro file.  Si noti poi come per questi ultimi le strutture
+\kstruct{file} nella \textit{file table}, pur essendo distinte, fanno
+riferimento allo stesso \textit{inode}, dato che il file che è stato aperto lo
+stesso. Questo è quello che avviene normalmente quando si apre più volte lo
+stesso file.
+
+Si ritrova quindi anche con le voci della \textit{file table} una situazione
+analoga di quella delle voci di una directory, con la possibilità di avere più
+voci che fanno riferimento allo stesso \textit{inode}. L'analogia è in realtà
+molto stretta perché quando si cancella un file, il kernel verifica anche che
+non resti nessun riferimento in una qualunque voce della \textit{file table}
+prima di liberare le risorse ad esso associate e disallocare il relativo
+\textit{inode}.
 
 Nelle vecchie versioni di Unix (ed anche in Linux fino al kernel 2.0.x) il
 numero di file aperti era anche soggetto ad un limite massimo dato dalle
@@ -214,16 +218,17 @@ più recenti non sussiste più, dato che si è passati da un vettore ad una
 lista, ma restano i limiti imposti dall'amministratore (vedi
 sez.~\ref{sec:sys_limits}).
 
+\itindend{file~table}
 
 
-\subsection{Apertura e creazione di un file}
-\label{sec:file_open}
+\subsection{Apertura, creazione e chiusura di un file}
+\label{sec:file_open_close}
 
 La funzione di sistema \funcd{open} è la principale funzione dell'interfaccia
 di gestione dei file, quella che dato un \textit{pathname} consente di
 ottenere un file descriptor ``\textsl{aprendo}'' il file
 corrispondente,\footnote{è \func{open} che alloca \kstruct{file}, la inserisce
-  nella \itindex{file~table} \textit{file table} e crea il riferimento nella
+  nella \textit{file table} e crea il riferimento nella
   \kstruct{files\_struct} del processo.} il suo prototipo è:
 
 \begin{funcproto}{
@@ -243,31 +248,43 @@ corrispondente,\footnote{è \func{open} che alloca \kstruct{file}, la inserisce
     \const{O\_CREAT} e \const{O\_EXCL}.
   \item[\errcode{EINTR}] la funzione era bloccata ed è stata interrotta da un
     segnale (vedi sez.~\ref{sec:sig_gen_beha}).
-  \item[\errcode{EISDIR}] \param{pathname} indica una directory e si è tentato
-    l'accesso in scrittura o in lettura/scrittura.
-  \item[\errcode{EFBIG}] il file è troppo grande per essere aperto (lo
-    standard richiederebbe \errval{EOVERFLOW}).
+  \item[\errcode{EINVAL}] si è usato \const{O\_CREAT} indicando un pathname
+    con caratteri non supportati dal filesystem sottostante o si è richiesto
+    \const{O\_TMPFILE} senza indicare \const{O\_WRONLY} o \const{O\_RDWR} o si
+    è usato \const{O\_DIRECT} per un filesystem che non lo supporta.
+  \item[\errcode{EISDIR}] \param{pathname} indica una directory e o si è
+    tentato un accesso che prevede la scrittura o si è usato
+    \const{O\_TMPFILE} con accesso che prevede la scrittura ma il kernel non
+    supporta la funzionalità.
+  \item[\errcode{EFBIG}] il file è troppo grande per essere aperto, in genere
+    dovuto al fatto che si è compilata una applicazione a 32 bit senza
+    abilitare il supporto per le dimensioni a 64 bit; questo è il valore
+    restituito fino al kernel 2.6.23, coi successivi viene restituito
+    \errcode{EOVERFLOW} come richiesto da POSIX.1.
   \item[\errcode{ELOOP}] si sono incontrati troppi collegamenti simbolici nel
     risolvere \param{pathname} o si è indicato \const{O\_NOFOLLOW} e
-    \param{pathname} è un collegamento simbolico.
+    \param{pathname} è un collegamento simbolico (e non si è usato
+    \const{O\_PATH}).
   \item[\errcode{ENODEV}] \param{pathname} si riferisce a un file di
     dispositivo che non esiste.
   \item[\errcode{ENOENT}] \param{pathname} non esiste e non si è richiesto
-    \const{O\_CREAT}, o non esiste un suo componente. 
+    \const{O\_CREAT}, o non esiste un suo componente, o si riferisce ad una
+    directory inesistente, si è usato \const{O\_TMPFILE} con accesso che
+    prevede la scrittura ma il kernel non supporta la funzionalità.
   \item[\errcode{ENOTDIR}] si è specificato \const{O\_DIRECTORY} e
     \param{pathname} non è una directory.
-  \item[\errcode{ENXIO}] si sono impostati \const{O\_NOBLOCK} o
-    \const{O\_WRONLY} ed il file è una fifo che non viene letta da nessun
-    processo o \param{pathname} è un file di dispositivo ma il dispositivo è
-    assente.
+  \item[\errcode{ENXIO}] si sono impostati \const{O\_NONBLOCK} o
+    \const{O\_WRONLY} ed il file è una \textit{fifo} che non viene letta da
+    nessun processo o \param{pathname} è un file di dispositivo ma il
+    dispositivo è assente.
   \item[\errcode{EPERM}] si è specificato \const{O\_NOATIME} e non si è né
     amministratori né proprietari del file.
   \item[\errcode{ETXTBSY}] si è cercato di accedere in scrittura all'immagine
     di un programma in esecuzione.
   \item[\errcode{EWOULDBLOCK}] la funzione si sarebbe bloccata ma si è
-    richiesto \const{O\_NOBLOCK}.
+    richiesto \const{O\_NONBLOCK}.
   \end{errlist}
-  ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{EMFILE},
+  ed inoltre \errval{EACCES}, \errval{EDQUOT}, \errval{EFAULT}, \errval{EMFILE},
   \errval{ENAMETOOLONG}, \errval{ENFILE}, \errval{ENOMEM}, \errval{ENOSPC},
   \errval{EROFS}, nel loro significato generico.}
 \end{funcproto}
@@ -276,47 +293,54 @@ La funzione apre il file indicato da \param{pathname} nella modalità indicata
 da \param{flags}. Essa può essere invocata in due modi diversi, specificando
 opzionalmente un terzo argomento \param{mode}. Qualora il file non esista e
 venga creato, questo argomento consente di indicare quali permessi dovranno
-essergli assegnati. I valori possibili sono gli stessi già visti in
+essergli assegnati.\footnote{questo è possibile solo se si è usato in
+  \param{flags} uno fra \const{O\_CREATE} e \const{O\_TMPFILE}, in tutti gli
+  altri casi sarà ignorato.} I valori possibili sono gli stessi già visti in
 sez.~\ref{sec:file_perm_overview} e possono essere specificati come OR binario
 delle costanti descritte in tab.~\ref{tab:file_bit_perm}. Questi permessi sono
-comunque filtrati dal valore della \itindex{umask} \textit{umask} (vedi
+comunque filtrati dal valore della \textit{umask} (vedi
 sez.~\ref{sec:file_perm_management}) del processo.
 
 La funzione restituisce sempre il primo file descriptor libero, una
 caratteristica che permette di prevedere qual è il valore del file descriptor
 che si otterrà al ritorno di \func{open}, e che viene spesso usata dalle
 applicazioni per sostituire i file corrispondenti ai file standard visti in
-tab.~\ref{tab:file_std_files}. Se ad esempio si chiude lo
-\itindex{standard~input} \textit{standard input} e si apre subito dopo un
-nuovo file questo diventerà il nuovo \itindex{standard~input} \textit{standard
-  input} dato che avrà il file descriptor 0.
+tab.~\ref{tab:file_std_files}. Se ad esempio si chiude lo \textit{standard
+  input} e si apre subito dopo un nuovo file questo diventerà il nuovo
+\textit{standard input} dato che avrà il file descriptor 0.
 
 Al momento dell'apertura il nuovo file descriptor non è condiviso con nessun
 altro processo (torneremo sul significato della condivisione dei file
 descriptor, che in genere si ottiene dopo una \func{fork}, in
-sez.~\ref{sec:file_sharing}) ed è impostato, come accennato in
+sez.~\ref{sec:file_shared_access}) ed è impostato, come accennato in
 sez.~\ref{sec:proc_exec}, per restare aperto attraverso una
 \func{exec}. Inoltre la posizione sul file, il cosiddetto \textit{offset}, è
 impostata all'inizio del file. Una volta aperto un file si potrà operare su di
 esso direttamente tramite il file descriptor, e quanto avviene al
 \textit{pathname} con cui lo si è aperto sarà del tutto ininfluente.
 
+\itindbeg{file~status~flags}
+
 Il comportamento della funzione, e le diverse modalità con cui può essere
 aperto il file, vengono controllati dall'argomento \param{flags} il cui valore
 deve essere indicato come maschera binaria in cui ciascun bit ha un
 significato specifico.  Alcuni di questi bit vanno anche a costituire i
-cosiddetti \textsl{flag di stato} del file (i cosiddetti
-\itindex{file~status~flag} \textit{file status flags}), che vengono mantenuti
-nel campo \var{f\_flags} della struttura \kstruct{file} che abbiamo riportato
-anche in fig.~\ref{fig:file_proc_file}).
+cosiddetti \textit{file status flags} (i \textsl{flag di stato} del file), che
+vengono mantenuti nel campo \var{f\_flags} della struttura \kstruct{file} che
+abbiamo riportato anche in fig.~\ref{fig:file_proc_file}).
 
 Ciascun flag viene identificato da una apposita costante, ed il valore
 di \param{flags} deve essere specificato come OR aritmetico di queste
-costanti. I vari bit che si possono usare come componenti di \param{flags}
-sono divisi in tre gruppi principali. Il primo gruppo è quello dei cosiddetti
-flag delle \textsl{modalità di accesso} (o \textit{access mode flags}), che
-specificano che tipo di accesso si effettuerà sul file, fra lettura, scrittura
-e lettura/scrittura. Questa modalità deve essere indicata usando una delle
+costanti. Inoltre per evitare problemi di compatibilità con funzionalità che
+non sono previste o non ancora supportate in versioni meno recenti del kernel,
+la \func{open} di Linux ignora i flag che non riconosce, pertanto
+l'indicazione di un flag inesistente non provoca una condizione di errore.
+
+I vari bit che si possono usare come componenti di \param{flags} sono divisi
+in tre gruppi principali. Il primo gruppo è quello dei cosiddetti flag delle
+\textsl{modalità di accesso} (o \textit{access mode flags}), che specificano
+che tipo di accesso si effettuerà sul file, fra lettura, scrittura e
+lettura/scrittura. Questa modalità deve essere indicata usando una delle
 costanti di tab.~\ref{tab:open_access_mode_flag}.
 
 \begin{table}[htb]
@@ -327,9 +351,9 @@ costanti di tab.~\ref{tab:open_access_mode_flag}.
       \textbf{Flag} & \textbf{Significato} \\
       \hline
       \hline
-      \const{O\_RDONLY} & Apre il file in sola lettura.\\
-      \const{O\_WRONLY} & Apre il file in sola scrittura.\\
-      \const{O\_RDWR}   & Apre il file sia in lettura che in scrittura.\\
+      \constd{O\_RDONLY} & Apre il file in sola lettura.\\
+      \constd{O\_WRONLY} & Apre il file in sola scrittura.\\
+      \constd{O\_RDWR}   & Apre il file sia in lettura che in scrittura.\\
       \hline
     \end{tabular}
     \caption{Le tre costanti che identificano le modalità di accesso
@@ -349,20 +373,22 @@ equivalente a \const{O\_RDWR}, e non deve essere usata.\footnote{in realtà
   driver, in cui si richiede la verifica della capacità di accesso in lettura
   e scrittura ma viene restituito un file descriptor che non può essere letto
   o scritto, ma solo usato con una \func{ioctl} (vedi
-  sez.~\ref{sec:file_ioctl}).}
+  sez.~\ref{sec:file_fcntl_ioctl}).}
 
 La modalità di accesso deve sempre essere specificata quando si apre un file,
-il valore indicato in \param{flags} viene salvato nei
-\itindex{file~status~flag} \textit{file status flags}, e può essere riletto
-con \func{fcntl} (vedi sez.~\ref{sec:file_fcntl}), il relativo valore può
-essere poi ottenuto un AND aritmetico della maschera binaria
-\const{O\_ACCMODE}, ma non può essere modificato. Nella \acr{glibc} sono
-definite inoltre \const{O\_READ} come sinonimo di \const{O\_RDONLY} e
-\const{O\_WRITE} come sinonimo di \const{O\_WRONLY}.\footnote{si tratta di
-  definizioni completamente fuori standard, attinenti, insieme a
-  \const{O\_EXEC} che permetterebbe l'apertura di un file per l'esecuzione, ad
-  un non meglio precisato ``\textit{GNU system}''; pur essendo equivalenti
-  alle definizioni classiche non è comunque il caso di utilizzarle.}
+il valore indicato in \param{flags} viene salvato nei \textit{file status
+  flags}, e può essere riletto con \func{fcntl} (vedi
+sez.~\ref{sec:file_fcntl_ioctl}), il relativo valore può essere poi ottenuto
+un AND aritmetico della maschera binaria \constd{O\_ACCMODE}, ma non può essere
+modificato. Nella \acr{glibc} sono definite inoltre \constd{O\_READ} come
+sinonimo di \const{O\_RDONLY} e \constd{O\_WRITE} come sinonimo di
+\const{O\_WRONLY}.\footnote{si tratta di definizioni completamente fuori
+  standard, attinenti, insieme a \constd{O\_EXEC} che permetterebbe l'apertura
+  di un file per l'esecuzione, ad un non meglio precisato ``\textit{GNU
+    system}''; pur essendo equivalenti alle definizioni classiche non è
+  comunque il caso di utilizzarle.}
+
+\itindend{file~status~flags}
 
 Il secondo gruppo di flag è quello delle \textsl{modalità di
   apertura},\footnote{la pagina di manuale di \func{open} parla di
@@ -373,8 +399,8 @@ Il secondo gruppo di flag è quello delle \textsl{modalità di
 permettono di specificare alcune delle caratteristiche del comportamento di
 \func{open} nel momento in viene eseguita per aprire un file. Questi flag
 hanno effetto solo nella chiamata della funzione, non sono memorizzati fra i
-\itindex{file~status~flag} \textit{file status flags} e non possono essere
-riletti da \func{fcntl} (vedi sez.~\ref{sec:file_fcntl}).
+\textit{file status flags} e non possono essere riletti da \func{fcntl} (vedi
+sez.~\ref{sec:file_fcntl_ioctl}).
 
 \begin{table}[htb]
   \centering
@@ -384,51 +410,56 @@ riletti da \func{fcntl} (vedi sez.~\ref{sec:file_fcntl}).
       \textbf{Flag} & \textbf{Significato} \\
       \hline
       \hline
-      \const{O\_CREAT} &    Se il file non esiste verrà creato, con le regole
-                            di titolarità del file viste in
-                            sez.~\ref{sec:file_ownership_management}. Se si
-                            imposta questo flag l'argomento \param{mode} deve
-                            essere sempre specificato.\\  
-      \const{O\_DIRECTORY}& Se \param{pathname} non è una directory la
-                            chiamata fallisce. Questo flag, introdotto con il
-                            kernel 2.1.126, è specifico di Linux e
-                            serve ad evitare dei possibili
-                            \itindex{Denial~of~Service~(DoS)}
-                            \textit{DoS}\footnotemark quando \func{opendir} 
-                            viene chiamata su una fifo o su un dispositivo
-                            associato ad una unità a nastri. Non viene
-                            usato al di fuori dell'implementazione di
-                            \func{opendir}, ed è utilizzabile soltanto se si è
-                            definita la macro \macro{\_GNU\_SOURCE}.\\
-      \const{O\_EXCL}     & Deve essere usato in congiunzione con
-                            \const{O\_CREAT} ed in tal caso impone che il file
-                            indicato da \param{pathname} non sia già esistente
-                            (altrimenti causa il fallimento della chiamata con
-                            un errore di \errcode{EEXIST}).\\
-      \const{O\_LARGEFILE}& Viene usato sui sistemi a 32 bit per richiedere
-                            l'apertura di file molto grandi, la cui
-                            dimensione non è rappresentabile con la versione a
-                            32 bit del tipo \type{off\_t}, utilizzando
-                            l'interfaccia alternativa abilitata con la
-                            macro \macro{\_LARGEFILE64\_SOURCE}. Come
-                            illustrato in sez.~\ref{sec:intro_gcc_glibc_std} è
-                            sempre preferibile usare la conversione automatica
-                            delle funzioni che si attiva assegnando a $64$ la
-                            macro \macro{\_FILE\_OFFSET\_BITS}, e non usare mai
-                            questo flag.\\
-      \const{O\_NOCTTY}   & Se \param{pathname} si riferisce ad un dispositivo
-                            di terminale, questo non diventerà il terminale di
-                            controllo, anche se il processo non ne ha ancora
-                            uno (si veda sez.~\ref{sec:sess_ctrl_term}).\\ 
-      \const{O\_NOFOLLOW} & Se \param{pathname} è un collegamento simbolico
+      \constd{O\_CREAT}  & Se il file non esiste verrà creato, con le regole
+                           di titolarità del file viste in
+                           sez.~\ref{sec:file_ownership_management}. Se si
+                           imposta questo flag l'argomento \param{mode} deve
+                           essere sempre specificato.\\  
+      \constd{O\_DIRECTORY}& Se \param{pathname} non è una directory la
+                             chiamata fallisce. Questo flag, introdotto con il
+                             kernel 2.1.126, è specifico di Linux e
+                             serve ad evitare dei possibili
+                             \itindex{Denial~of~Service~(DoS)}
+                             \textit{DoS}\footnotemark quando \func{opendir} 
+                             viene chiamata su una \textit{fifo} o su un
+                             dispositivo associato ad una unità a nastri. Non
+                             viene usato al di fuori dell'implementazione di
+                             \func{opendir}, ed è utilizzabile soltanto se si è
+                             definita la macro \macro{\_GNU\_SOURCE}.\\
+      \constd{O\_EXCL}   & Deve essere usato in congiunzione con
+                           \const{O\_CREAT} ed in tal caso impone che il file
+                           indicato da \param{pathname} non sia già esistente
+                           (altrimenti causa il fallimento della chiamata con
+                           un errore di \errcode{EEXIST}).\\
+      \constd{O\_LARGEFILE}& Viene usato sui sistemi a 32 bit per richiedere
+                             l'apertura di file molto grandi, la cui
+                             dimensione non è rappresentabile con la versione a
+                             32 bit del tipo \type{off\_t}, utilizzando
+                             l'interfaccia alternativa abilitata con la
+                             macro \macro{\_LARGEFILE64\_SOURCE}. Come
+                             illustrato in sez.~\ref{sec:intro_gcc_glibc_std} è
+                             sempre preferibile usare la conversione automatica
+                             delle funzioni che si attiva assegnando a $64$ la
+                             macro \macro{\_FILE\_OFFSET\_BITS}, e non usare mai
+                             questo flag.\\
+      \constd{O\_NOCTTY} & Se \param{pathname} si riferisce ad un dispositivo
+                           di terminale, questo non diventerà il terminale di
+                           controllo, anche se il processo non ne ha ancora
+                           uno (si veda sez.~\ref{sec:sess_ctrl_term}).\\ 
+      \constd{O\_NOFOLLOW}& Se \param{pathname} è un collegamento simbolico
                             la chiamata fallisce. Questa è un'estensione BSD
                             aggiunta in Linux a partire dal kernel
                             2.1.126, ed utilizzabile soltanto se si è definita
-                            la macro \macro{\_GNU\_SOURCE}.\\ 
-      \const{O\_TRUNC}    & Se usato su un file di dati aperto in scrittura,
-                            ne tronca la lunghezza a zero; con un terminale o
-                            una fifo viene ignorato, negli altri casi il
-                            comportamento non è specificato.\\ 
+                            la macro \macro{\_GNU\_SOURCE}.\\
+      \const{O\_TMPFILE} & Consente di creare un file temporaneo anonimo, non
+                           visibile con un pathname sul filesystem, ma
+                           leggibile e scrivibile all'interno del processo.
+                           Introdotto con il kernel 3.11, è specifico di
+                           Linux.\\ 
+      \constd{O\_TRUNC}  & Se usato su un file di dati aperto in scrittura,
+                           ne tronca la lunghezza a zero; con un terminale o
+                           una \textit{fifo} viene ignorato, negli altri casi
+                           il comportamento non è specificato.\\ 
       \hline
     \end{tabular}
     \caption{Le costanti che identificano le \textit{modalità di apertura} di
@@ -443,36 +474,93 @@ riletti da \func{fcntl} (vedi sez.~\ref{sec:file_fcntl}).
 
 Si è riportato in tab.~\ref{tab:open_time_flag} l'elenco dei flag delle
 \textsl{modalità di apertura}.\footnote{la \acr{glibc} definisce anche i due
-  flag \const{O\_SHLOCK}, che aprirebbe il file con uno \textit{shared lock} e
-  \const{O\_EXLOCK} che lo aprirebbe con un \textit{exclusive lock} (vedi
-  sez.~\ref{sec:file_locking}, si tratta di opzioni specifiche di BSD, che non
+  flag \constd{O\_SHLOCK}, che aprirebbe il file con uno \textit{shared lock}
+  e \constd{O\_EXLOCK} che lo aprirebbe con un \textit{exclusive lock} (vedi
+  sez.~\ref{sec:file_locking}), si tratta di opzioni specifiche di BSD, che non
   esistono con Linux.}  Uno di questi, \const{O\_EXCL}, ha senso solo se usato
 in combinazione a \const{O\_CREAT} quando si vuole creare un nuovo file per
 assicurarsi che questo non esista di già, e lo si usa spesso per creare i
-cosiddetti \index{file!di lock} ``\textsl{file di lock}'' (vedi
-sez.~\ref{sec:ipc_file_lock}). Si tenga presente che questa opzione è
-supportata su NFS solo a partire da NFSv3 e con il kernel 2.6, nelle versioni
-precedenti la funzionalità viene emulata controllando prima l'esistenza del
-file per cui usarla per creare \index{file!di lock} un file di lock potrebbe
-dar luogo a una \itindex{race~condition} \textit{race condition}.\footnote{un
-  file potrebbe venir creato fra il controllo la successiva apertura con
-  \const{O\_CREAT}, la cosa si può risolvere comunque creando un file con un
-  nome univoco ed usando la funzione \func{link} per creare il \index{file!di
-    lock} file di lock, (vedi sez.~\ref{sec:ipc_file_lock}).}
+cosiddetti ``\textsl{file di lock}'' (vedi sez.~\ref{sec:ipc_file_lock}).
+
+Si tenga presente che questa opzione è supportata su NFS solo a partire da
+NFSv3 e con il kernel 2.6, nelle versioni precedenti la funzionalità viene
+emulata controllando prima l'esistenza del file per cui usarla per creare un
+file di lock potrebbe dar luogo a una \textit{race condition}, in tal caso
+infatti un file potrebbe venir creato fra il controllo la successiva apertura
+con \const{O\_CREAT}; la cosa si può risolvere comunque creando un file con un
+nome univoco ed usando la funzione \func{link} per creare il file di lock,
+(vedi sez.~\ref{sec:ipc_file_lock}).
 
 Se si usa \const{O\_EXCL} senza \const{O\_CREAT} il comportamento è
-indefinito.  Nella creazione di un file con \const{O\_CREAT} occorre sempre
-specificare l'argomento di \param{mode}, che altrimenti è ignorato. Si tenga
-presente che indipendentemente dai permessi che si possono assegnare, che in
-seguito potrebbero non consentire lettura o scrittura, quando il file viene
-aperto l'accesso viene garantito secondo quanto richiesto con i flag di
+indefinito, escluso il caso in cui viene usato con \const{O\_TMPFILE} su cui
+torneremo più avanti; un'altra eccezione è quello in cui lo si usa da solo su
+un file di dispositivo, in quel caso se questo è in uso (ad esempio se è
+relativo ad un filesystem che si è montato) si avrà un errore di
+\errval{EBUSY}, e pertanto può essere usato in questa modalità per rilevare lo
+stato del dispositivo.
+
+Nella creazione di un file con \const{O\_CREAT} occorre sempre specificare
+l'argomento di \param{mode}, che altrimenti è ignorato. Si tenga presente che
+indipendentemente dai permessi che si possono assegnare, che in seguito
+potrebbero non consentire lettura o scrittura, quando il file viene aperto
+l'accesso viene garantito secondo quanto richiesto con i flag di
 tab.~\ref{tab:open_access_mode_flag}.  Quando viene creato un nuovo file
 \const{O\_CREAT} con tutti e tre i tempi del file di
 tab.~\ref{tab:file_file_times} vengono impostati al tempo corrente. Se invece
 si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il
 \textit{modification time} e lo \textit{status change time}.
 
-\begin{table}[htb]
+Il flag \constd{O\_TMPFILE}, introdotto con il kernel
+3.11,\footnote{inizialmente solo su alcuni filesystem (i vari \acr{extN},
+  \acr{Minix}, \acr{UDF}, \acr{shmem}) poi progressivamente esteso ad altri
+  (\acr{XFS} con il 3.15, \acr{Btrfs} e \acr{F2FS} con il 3.16, \acr{ubifs}
+  con il 4.9).}  consente di aprire un file temporaneo senza che questo venga
+associato ad un nome e compaia nel filesystem. In questo caso la funzione
+restituirà un file descriptor da poter utilizzare per leggere e scrivere dati,
+ma il contenuto dell'argomento \param{path} verrà usato solamente per
+determinare, in base alla directory su cui si verrebbe a trovare il
+\textit{pathname} indicato, il filesystem all'interno del quale deve essere
+allocato l'\textit{inode} e lo spazio disco usato dal file
+descriptor. L'\textit{inode} resterà anonimo e l'unico riferimento esistente
+sarà quello contenuto nella \textit{file table} del processo che ha chiamato
+\func{open}.
+
+Lo scopo principale del flag è quello fornire una modalità atomica, semplice e
+sicura per applicare la tecnica della creazione di un file temporaneo seguita
+dalla sua immediata cancellazione con \func{unlink} per non lasciare rimasugli
+sul filesystem, di cui è parlato in sez.~\ref{sec:link_symlink_rename}.
+Inoltre, dato che il file non compare nel filesystem, si evitano alla radice
+tutti gli eventuali problemi di \textit{race condition} o \textit{symlink
+  attack} e non ci si deve neanche preoccupare di ottenere un opportuno nome
+univoco con l'uso delle funzioni di sez.~\ref{sec:file_temp_file}.
+
+Una volta aperto il file vi si potrà leggere o scrivere a seconda che siano
+utilizzati \const{O\_RDWR} o \const{O\_WRONLY}, mentre l'uso di
+\func{O\_RDONLY} non è consentito, non avendo molto senso ottenere un file
+descriptor da cui non si potrà comunque mai leggere nulla. L'unico altro flag
+che può essere utilizzato insieme a \const{O\_TMPFILE} è \const{O\_EXCL}, che
+in questo caso assume però un significato diverso da quello ordinario, dato
+che in questo caso non avrebbe senso fallire se il file non esiste, dato che
+questo è sempre vero.
+
+L'uso di \const{O\_EXCL} attiene all'altro possibile impiego di
+\const{O\_TMPFILE} oltre a quello della creazione sicura di un file temporaneo
+come sostituto di \func{tmpfile}: la possibilità di creare un eventuale
+contenuto iniziale ed impostare permessi, proprietario e attributi estesi con
+\func{fchmod}, \func{fchown} e \func{fsetxattr} operando sul file descriptor,
+senza possibilità di \textit{race condition} ed interferenze esterne, per poi
+far apparire il tutto sul filesystem in un secondo tempo utilizzando
+\func{linkat} sul file descriptor (torneremo su questo in
+sez.~\ref{sec:file_openat}) per dargli un nome. Questa operazione però non
+sarà possibile se si è usato \const{O\_EXCL}, che in questo caso viene ad
+assumere il significato di escludere la possibilità di far esistere il file
+anche in un secondo tempo.
+
+% NOTE: per O_TMPFILE vedi: http://kernelnewbies.org/Linux_3.11
+% https://lwn.net/Articles/558598/ http://lwn.net/Articles/619146/
+
+
+\begin{table}[!htb]
   \centering
   \footnotesize
     \begin{tabular}[c]{|l|p{10 cm}|}
@@ -480,70 +568,81 @@ si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il
       \textbf{Flag} & \textbf{Significato} \\
       \hline
       \hline
-      \const{O\_APPEND}  & Il file viene aperto in \itindex{append~mode}
-                           \textit{append mode}. La posizione sul file (vedi
-                           sez.~\ref{sec:file_lseek}) viene sempre mantenuta
-                           sulla sua coda, per cui quanto si scrive
-                           viene sempre aggiunto al contenuto precedente. Con
-                           NFS questa funzionalità non è supportata 
-                           e viene emulata, per questo possono verificarsi
-                           \itindex{race~condition} \textit{race 
-                             condition} con una sovrapposizione dei dati se
-                           più di un processo scrive allo stesso tempo. \\
-      \const{O\_ASYNC}   & Apre il file per l'I/O in modalità asincrona (vedi
-                           sez.~\ref{sec:file_asyncronous_io}). Quando è
+      \constd{O\_APPEND} & Il file viene aperto in \textit{append mode}. La
+                           posizione sul file (vedi sez.~\ref{sec:file_lseek})
+                           viene sempre mantenuta sulla sua coda, per cui
+                           quanto si scrive viene sempre aggiunto al contenuto
+                           precedente. Con NFS questa funzionalità non è
+                           supportata e viene emulata, per questo possono
+                           verificarsi \textit{race condition} con una
+                           sovrapposizione dei dati se più di un processo
+                           scrive allo stesso tempo.\\ 
+      \constd{O\_ASYNC}  & Apre il file per l'I/O in modalità asincrona (vedi
+                           sez.~\ref{sec:signal_driven_io}). Quando è
                            impostato viene generato il segnale \signal{SIGIO}
                            tutte le volte che il file è pronto per le
                            operazioni di lettura o scrittura. Questo flag si
                            può usare solo terminali, pseudo-terminali e socket
-                           e, a partire dal kernel 2.6, anche sulle fifo.\\ 
-      \const{O\_CLOEXEC}&  Attiva la modalità di \itindex{close-on-exec}
-                           \textit{close-on-exec} (vedi
+                           e, a partire dal kernel 2.6, anche sulle
+                           \textit{fifo}. Per un bug dell'implementazione non
+                           è opportuno usarlo in fase di apertura del file,
+                           deve invece essere attivato successivamente con
+                           \func{fcntl}.\\
+      \constd{O\_CLOEXEC}& Attiva la modalità di \textit{close-on-exec} (vedi
                            sez.~\ref{sec:proc_exec}) sul file. Il flag è 
                            previsto dallo standard POSIX.1-2008, ed è stato
                            introdotto con il kernel 2.6.23 per evitare una
-                           \itindex{race~condition} \textit{race condition}
-                           che si potrebbe verificare con i \textit{thread}
-                           fra l'apertura del file e l'impostazione della
-                           suddetta modalità con \func{fcntl} (vedi
-                           sez.~\ref{sec:file_fcntl}).\\
+                           \textit{race condition} che si potrebbe verificare
+                           con i \textit{thread} fra l'apertura del file e
+                           l'impostazione della suddetta modalità con
+                           \func{fcntl} (vedi
+                           sez.~\ref{sec:file_fcntl_ioctl}).\\ 
       \const{O\_DIRECT}  & Esegue l'I/O direttamente dalla memoria in
                            \textit{user space} in maniera sincrona, in modo da
                            scavalcare i meccanismi di bufferizzazione del
                            kernel. Introdotto con il kernel 2.4.10 ed
                            utilizzabile soltanto se si è definita la 
                            macro \macro{\_GNU\_SOURCE}.\\ 
-      \const{O\_NOATIME} & Blocca l'aggiornamento dei tempi di accesso dei
+      \constd{O\_NOATIME}& Blocca l'aggiornamento dei tempi di accesso dei
                            file (vedi sez.~\ref{sec:file_file_times}). Per
                            molti filesystem questa funzionalità non è
                            disponibile per il singolo file ma come opzione
-                           generale da specificare in fase di montaggio.\\ 
-      \const{O\_NONBLOCK}& Apre il file in \textsl{modalità non bloccante} per
-                           le operazioni di I/O (vedi
-                           sez.~\ref{sec:file_noblocking}). Questo significa
-                           il fallimento delle successive operazioni di
-                           lettura o scrittura qualora il file non sia pronto
-                           per la loro esecuzione immediata, invece del 
-                           blocco delle stesse in attesa di una successiva
-                           possibilità di esecuzione come avviene
-                           normalmente. Questa modalità ha senso solo per le
-                           fifo, vedi sez.~\ref{sec:ipc_named_pipe}), o quando
-                           si vuole aprire un file di dispositivo per eseguire
-                           una \func{ioctl} (vedi
-                           sez.~\ref{sec:file_ioctl}).\\ 
-      \const{O\_NDELAY}  & In Linux è un sinonimo di \const{O\_NONBLOCK}, ma
+                           generale da specificare in fase di
+                           montaggio. Introdotto con il kernel 2.6.8 ed 
+                           utilizzabile soltanto se si è definita la 
+                           macro \macro{\_GNU\_SOURCE}.\\ 
+      \constd{O\_NONBLOCK}& Apre il file in \textsl{modalità non bloccante} per
+                            le operazioni di I/O (vedi
+                            sez.~\ref{sec:file_noblocking}). Questo significa
+                            il fallimento delle successive operazioni di
+                            lettura o scrittura qualora il file non sia pronto
+                            per la loro esecuzione immediata, invece del 
+                            blocco delle stesse in attesa di una successiva
+                            possibilità di esecuzione come avviene
+                            normalmente. Questa modalità ha senso solo per le
+                            \textit{fifo}, vedi sez.~\ref{sec:ipc_named_pipe}),
+                            o quando si vuole aprire un file di dispositivo
+                            per eseguire una \func{ioctl} (vedi
+                            sez.~\ref{sec:file_fcntl_ioctl}).\\ 
+      \constd{O\_NDELAY} & In Linux è un sinonimo di \const{O\_NONBLOCK}, ma
                            origina da SVr4, dove però causava il ritorno da
                            una \func{read} con un valore nullo e non con un
                            errore, questo introduce un'ambiguità, dato che
                            come vedremo in sez.~\ref{sec:file_read} il ritorno
                            di un valore nullo da parte di \func{read} ha 
                            il significato di una \textit{end-of-file}.\\
-      \const{O\_SYNC}    & Apre il file per l'input/output sincrono. Ogni
+      \const{O\_PATH}    & Ottiene un file descriptor io cui uso è limitato
+                           all'indicare una posizione sul filesystem o
+                           eseguire operazioni che operano solo a livello del
+                           file descriptor (e non di accesso al contenuto del
+                           file). Introdotto con il kernel 2.6.39, è specifico
+                           di Linux.\\
+      \constd{O\_SYNC}   & Apre il file per l'input/output sincrono. Ogni
                            scrittura si bloccherà fino alla conferma
                            dell'arrivo di tutti i dati e di tutti i metadati
                            sull'hardware sottostante (in questo significato
                            solo dal kernel 2.6.33).\\
-      \const{O\_DSYNC}   & Apre il file per l'input/output sincrono. Ogni
+      \constd{O\_DSYNC}  & Apre il file per l'input/output sincrono. Ogni
                            scrittura di dati si bloccherà fino alla conferma
                            dell'arrivo degli stessi e della parte di metadati
                            ad essi relativa sull'hardware sottostante (in
@@ -558,24 +657,37 @@ si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il
 Il terzo gruppo è quello dei flag delle \textsl{modalità di operazione},
 riportati in tab.~\ref{tab:open_operation_flag}, che permettono di specificare
 varie caratteristiche del comportamento delle operazioni di I/O che verranno
-eseguite sul file. Tutti questi, tranne \const{O\_CLOEXEC}, che viene
-mantenuto per ogni singolo file descriptor, vengono salvati nel campo
-\var{f\_flags} della struttura \kstruct{file} insieme al valore della
-\textsl{modalità di accesso} andando far parte dei cosiddetti \textit{file
-  status flags}. Il loro valore viene impostato alla chiamata di \func{open},
-ma possono essere riletti ed in alcuni di essi anche modificati, con
-conseguente effetto sulle caratteristiche operative che controllano, con
-\func{fcntl} (vedi sez.~\ref{sec:file_fcntl}).
-
-Il flag \const{O\_DIRECT} non è previsto da nessuno standard, anche se è
+eseguite sul file o le modalità in cui lo si potrà utilizzare. Tutti questi,
+tranne \const{O\_CLOEXEC}, che viene mantenuto per ogni singolo file
+descriptor, vengono salvati nel campo \var{f\_flags} della struttura
+\kstruct{file} insieme al valore della \textsl{modalità di accesso}, andando
+far parte dei \textit{file status flags}. Il loro valore viene impostato alla
+chiamata di \func{open}, ma possono venire riletti in un secondo tempo con
+\func{fcntl}, inoltre alcuni di essi possono anche essere modificati tramite
+questa funzione, con conseguente effetto sulle caratteristiche operative che
+controllano (torneremo sull'argomento in sez.~\ref{sec:file_fcntl_ioctl}).
+
+Il flag \const{O\_ASYNC} (che, per compatibilità con BSD, si può indicare
+anche con la costante \constd{FASYNC}) è definito come possibile valore per
+\func{open}, ma per un bug dell'implementazione,\footnote{segnalato come
+  ancora presente nella pagina di manuale, almeno fino al novembre 2018.} non
+solo non attiva il comportamento citato, ma se usato richiede di essere
+esplicitamente disattivato prima di essere attivato in maniera effettiva con
+l'uso di \func{fcntl}. Per questo motivo, non essendovi nessuna necessità
+specifica di definirlo in fase di apertura del file, è sempre opportuno
+attivarlo in un secondo tempo con \func{fcntl} (vedi
+sez.~\ref{sec:file_fcntl_ioctl}).
+
+Il flag \constd{O\_DIRECT} non è previsto da nessuno standard, anche se è
 presente in alcuni kernel unix-like.\footnote{il flag è stato introdotto dalla
   SGI in IRIX, ma è presente senza limiti di allineamento dei buffer anche in
   FreeBSD.} Per i kernel della serie 2.4 si deve garantire che i buffer in
 \textit{user space} da cui si effettua il trasferimento diretto dei dati siano
 allineati alle dimensioni dei blocchi del filesystem. Con il kernel 2.6 in
 genere basta che siano allineati a multipli di 512 byte, ma le restrizioni
-possono variare a seconda del filesystem, ed inoltre su alcuni filesystem può
-non essere supportato, nel qual caso si avrà un errore di \errval{EINVAL}.
+possono variare a seconda del filesystem, ed inoltre su alcuni filesystem
+questo flag può non essere supportato, nel qual caso si avrà un errore di
+\errval{EINVAL}.
 
 Lo scopo di \const{O\_DIRECT} è consentire un completo controllo sulla
 bufferizzazione dei propri dati per quelle applicazioni (in genere database)
@@ -588,28 +700,30 @@ ordinario, in quante le esigenze di mantenere coerenti i dati porterebbero ad
 un peggioramento delle prestazioni. Lo stesso dicasi per l'interazione con
 eventuale mappatura in memoria del file (vedi sez.~\ref{sec:file_memory_map}).
 
-Si tenga presente infine che anche se l'uso di \const{O\_DIRECT} comporta
-sostanzialmente solo una scrittura sincrona dei dati dei buffer in
-\textit{user space}, questo non è completamente equivalente all'uso di
-\const{O\_SYNC} che garantisce anche sulla scrittura sincrona dei metadati
-associati alla scrittura dei dati del file. Per questo in genere è opportuno
-se si usa \const{O\_DIRECT} è opportuno richiedere anche \const{O\_SYNC}.
+Si tenga presente infine che anche se l'uso di \const{O\_DIRECT} comporta una
+scrittura sincrona dei dati dei buffer in \textit{user space}, questo non è
+completamente equivalente all'uso di \const{O\_SYNC} che garantisce anche
+sulla scrittura sincrona dei metadati associati alla scrittura dei dati del
+file.\footnote{la situazione si complica ulteriormente per NFS, in cui l'uso
+  del flag disabilita la bufferizzazione solo dal lato del client, e può
+  causare problemi di prestazioni.} Per questo in genere se si usa
+\const{O\_DIRECT} è opportuno richiedere anche \const{O\_SYNC}.
 
 Si tenga presente infine che la implementazione di \const{O\_SYNC} di Linux
 differisce da quanto previsto dallo standard POSIX.1 che prevede, oltre a
 questo flag che dovrebbe indicare la sincronizzazione completa di tutti i dati
-e di tutti i metadati, altri due flag \const{O\_DSYNC} e \const{O\_RSYNC}. Il
-primo dei due richiede la scrittura sincrona di tutti i dati del file e dei
+e di tutti i metadati, altri due flag \const{O\_DSYNC} e \const{O\_RSYNC}. 
+
+Il primo dei due richiede la scrittura sincrona di tutti i dati del file e dei
 metadati che ne consentono l'immediata rilettura, ma non di tutti i metadati,
 per evitare la perdita di prestazioni relativa alla sincronizzazione di
-informazioni ausiliarie come i tempi dei file. 
-
-Il secondo, da usare in combinazione con \const{O\_SYNC} o \const{O\_DSYNC} ne
-sospende l'effetto, consentendo al kernel di bufferizzare le scritture, ma
-soltanto finché non avviene una lettura, in quel caso i dati ed i metadati
-dovranno essere sincronizzati immediatamente (secondo le modalità indicate da
-\const{O\_SYNC} e \const{O\_DSYNC}) e la lettura verrà bloccata fintanto che
-detta sincronizzazione non sia completata.
+informazioni ausiliarie come i tempi dei file.  Il secondo, da usare in
+combinazione con \const{O\_SYNC} o \const{O\_DSYNC} ne sospende l'effetto,
+consentendo al kernel di bufferizzare le scritture, ma soltanto finché non
+avviene una lettura, in quel caso i dati ed i metadati dovranno essere
+sincronizzati immediatamente (secondo le modalità indicate da \const{O\_SYNC}
+e \const{O\_DSYNC}) e la lettura verrà bloccata fintanto che detta
+sincronizzazione non sia completata.
 
 Nel caso di Linux, fino al kernel 2.6.33, esisteva solo \const{O\_SYNC}, ma
 con il comportamento previsto dallo standard per \const{O\_DSYNC}, e sia
@@ -617,11 +731,68 @@ questo che \const{O\_RSYNC} erano definiti (fin dal kernel 2.1.130) come
 sinonimi di \const{O\_SYNC}.  Con il kernel 2.6.33 il significato di
 \const{O\_SYNC} è diventato quello dello standard, ma gli è stato assegnato un
 valore diverso, mantenendo quello originario, con il comportamento
-corrispondete, per \const{O\_DSYNC}.
+corrispondete, per \const{O\_DSYNC} in modo che applicazioni compilate con
+versioni precedenti delle librerie e del kernel non trovassero un
+comportamento diverso.  Inoltre il nuovo \const{O\_SYNC} è stato definito in
+maniera opportuna in modo che su versioni del kernel precedenti la 2.6.33
+torni a corrispondere al valore di \const{O\_DSYNC}.
 
 % NOTE: per le differenze fra O_DSYNC, O_SYNC e O_RSYNC introdotte nella  
 % nello sviluppo del kernel 2.6.33, vedi http://lwn.net/Articles/350219/ 
 
+Il flag \constd{O\_PATH}, introdotto con il kernel 2.6.39, viene usato per
+limitare l'uso del file descriptor restituito da \func{open} o
+all'identificazione di una posizione sul filesystem (ad uso delle
+\textit{at-functions} che tratteremo in sez.~\ref{sec:file_openat}) o alle
+operazioni che riguardano il file descriptor in quanto tale, senza consentire
+operazioni sul file; in sostanza se si apre un file con \const{O\_PATH} si
+potrà soltanto:
+\begin{itemize*}
+\item usare il file descriptor come indicatore della directory di partenza con
+  una delle \textit{at-functions} (vedi sez.~\ref{sec:file_openat});
+\item cambiare directory di lavoro con \func{fchdir} se il file descriptor fa
+  riferimento a una directory (dal kernel 3.5);
+\item usare le funzioni che duplicano il file descriptor (vedi
+  sez.~\ref{sec:file_dup});
+\item passare il file descriptor ad un altro processo usando un socket
+  \const{PF\_UNIX} (vedi sez.~\ref{sec:unix_socket})
+\item ottenere le informazioni relative al file con \func{fstat} (dal kernel
+  3.6) o al filesystem con \func{fstatfs} (dal kernel 3.12);
+\item ottenere il valore dei \textit{file descriptor flags} (fra cui comparirà
+  anche lo stesso \const{O\_PATH}) o impostare o leggere i \textit{file status
+    flags} con \func{fcntl} (rispettivamente con le operazioni
+  \const{F\_GETFL}, \const{F\_SETFD} e \const{F\_GETFD}, vedi
+  sez.~\ref{sec:file_fcntl_ioctl}).
+\item chiudere il file con \func{close}.
+\end{itemize*}
+
+In realtà usando \const{O\_PATH} il file non viene effettivamente aperto, per
+cui ogni tentativo di usare il file descriptor così ottenuto con funzioni che
+operano effettivamente sul file (come ad esempio \func{read}, \func{write},
+\func{fchown}, \func{fchmod}, \func{ioctl}, ecc.) fallirà con un errore di
+\errval{EBADF}, come se questo non fosse un file descriptor valido. Per questo
+motivo usando questo flag non è necessario avere nessun permesso per aprire un
+file, neanche quello di lettura (occorre ovviamente avere il permesso di
+esecuzione per le directory sovrastanti).
+
+Questo consente di usare il file descriptor con funzioni che non richiedono
+permessi sul file, come \func{fstat}, laddove un'apertura con
+\const{O\_RDONLY} sarebbe fallita. I permessi verranno eventualmente
+controllati, se necessario, nelle operazioni seguenti, ad esempio per usare
+\func{fchdir} con il file descriptor (se questo fa riferimento ad una
+directory) occorrerà avere il permesso di esecuzione.
+
+Se si usa \const{O\_PATH} tutti gli altri flag eccettuati \const{O\_CLOEXEC},
+\const{O\_DIRECTORY} e \const{O\_NOFOLLOW} verranno ignorati. I primi due
+mantengono il loro significato usuale, mentre \const{O\_NOFOLLOW} fa si che se
+il file indicato è un un link simbolico venga aperto quest'ultimo (cambiando
+quindi il comportamento ordinario che prova il fallimento della chiamata),
+così da poter usare il file descriptor ottenuto per le funzioni
+\func{fchownat}, \func{fstatat}, \func{linkat} e \func{readlinkat} che ne
+supportano l'uso come come primo argomento (torneremo su questo in
+sez.~\ref{sec:file_openat}).
+
+
 Nelle prime versioni di Unix i valori di \param{flag} specificabili per
 \func{open} erano solo quelli relativi alle modalità di accesso del file.  Per
 questo motivo per creare un nuovo file c'era una \textit{system call}
@@ -644,10 +815,6 @@ dall'argomento \param{mode}. È del tutto equivalente a \code{open(filedes,
   O\_CREAT|O\_WRONLY|O\_TRUNC, mode)} e resta solo per compatibilità con i
 vecchi programmi.
 
-
-\subsection{La funzione \func{close}}
-\label{sec:file_close}
-
 Una volta che l'accesso ad un file non sia più necessario la funzione di
 sistema \funcd{close} permette di ``\textsl{chiuderlo}'', in questo modo il
 file non sarà più accessibile ed il relativo file descriptor ritornerà
@@ -668,14 +835,14 @@ disponibile; il suo prototipo è:
   ed inoltre \errval{EIO} nel suo significato generico.}
 \end{funcproto}
 
-La funzione chiude il file descriptor \param{fd}, la chiusura rilascia ogni
-blocco (il \textit{file locking} \itindex{file~locking} è trattato in
+La funzione chiude il file descriptor \param{fd}. La chiusura rilascia ogni
+eventuale blocco (il \textit{file locking} è trattato in
 sez.~\ref{sec:file_locking}) che il processo poteva avere acquisito su di
 esso. Se \param{fd} è l'ultimo riferimento (di eventuali copie, vedi
-sez.~\ref{sec:file_sharing} e \ref{sec:file_dup}) ad un file aperto, tutte le
-risorse nella \itindex{file~table} \textit{file table} vengono
-rilasciate. Infine se il file descriptor era l'ultimo riferimento ad un file
-su disco quest'ultimo viene cancellato.
+sez.~\ref{sec:file_shared_access} e \ref{sec:file_dup}) ad un file aperto,
+tutte le risorse nella \textit{file table} vengono rilasciate. Infine se il
+file descriptor era l'ultimo riferimento ad un file su disco quest'ultimo
+viene cancellato.
 
 Si ricordi che quando un processo termina tutti i suoi file descriptor vengono
 automaticamente chiusi, molti programmi sfruttano questa caratteristica e non
@@ -694,9 +861,10 @@ siano stati effettivamente scritti su disco, perché il kernel può decidere di
 ottimizzare l'accesso a disco ritardandone la scrittura. L'uso della funzione
 \func{sync} (vedi sez.~\ref{sec:file_sync}) effettua esplicitamente il
 \emph{flush} dei dati, ma anche in questo caso resta l'incertezza dovuta al
-comportamento dell'hardware (che a sua volta può introdurre ottimizzazioni
-dell'accesso al disco che ritardano la scrittura dei dati, da cui l'abitudine
-di ripetere tre volte il comando prima di eseguire lo shutdown).
+comportamento dell'hardware, che a sua volta può introdurre ottimizzazioni
+dell'accesso al disco che ritardano la scrittura dei dati. Da questo deriva
+l'abitudine di alcuni sistemisti di ripetere tre volte il comando omonimo
+prima di eseguire lo shutdown di una macchina.
 
 
 \subsection{La gestione della posizione nel file}
@@ -709,68 +877,77 @@ intero positivo che esprime il numero di byte dall'inizio del file. Tutte le
 operazioni di lettura e scrittura avvengono a partire da questa posizione che
 viene automaticamente spostata in avanti del numero di byte letti o scritti.
 
-In genere, a meno di non avere richiesto la modalità \itindex{append~mode} di
-\textit{append} con \const{O\_APPEND}, questa posizione viene impostata a zero
-all'apertura del file. È possibile impostarla ad un valore qualsiasi con la
-funzione si sistema \funcd{lseek}, il cui prototipo è:
+In genere, a meno di non avere richiesto la modalità di scrittura in
+\textit{append} (vedi sez.~\ref{sec:file_write}) con \const{O\_APPEND}, questa
+posizione viene impostata a zero all'apertura del file. È possibile impostarla
+ad un valore qualsiasi con la funzione di sistema \funcd{lseek}, il cui
+prototipo è:
 
 \begin{funcproto}{
 \fhead{sys/types.h}
 \fhead{unistd.h}
 \fdecl{off\_t lseek(int fd, off\_t offset, int whence)}
-\fdesc{Imposta la posizione sul file..
+\fdesc{Imposta la posizione sul file.} 
 }
 
 {La funzione ritorna il valore della posizione sul file in caso di successo e
   $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-    \item[\errcode{ESPIPE}] \param{fd} è una pipe, un socket o una fifo.
     \item[\errcode{EINVAL}] \param{whence} non è un valore valido.
     \item[\errcode{EOVERFLOW}] \param{offset} non può essere rappresentato nel
       tipo \type{off\_t}.
+    \item[\errcode{ESPIPE}] \param{fd} è una \textit{pipe}, un socket o una
+      \textit{fifo}.
   \end{errlist}
   ed inoltre \errval{EBADF} nel suo significato generico.}
 \end{funcproto}
 
-La funzione imposta la nuova posizione sul file usando il valore specificato
+La funzione imposta la nuova posizione sul file usando il valore indicato
 da \param{offset}, che viene sommato al riferimento dato
-dall'argomento \param{whence}. Quest'ultimo deve essere indicato con una delle
-costanti riportate in tab.~\ref{tab:lseek_whence_values}.\footnote{per
-  compatibilità con alcune vecchie notazioni questi valori possono essere
-  rimpiazzati rispettivamente con 0, 1 e 2 o con \const{L\_SET},
-  \const{L\_INCR} e \const{L\_XTND}.} 
+dall'argomento \param{whence}, che deve essere indicato con una delle costanti
+riportate in tab.~\ref{tab:lseek_whence_values}.\footnote{per compatibilità
+  con alcune vecchie notazioni questi valori possono essere rimpiazzati
+  rispettivamente con 0, 1 e 2 o con \constd{L\_SET}, \constd{L\_INCR} e
+  \constd{L\_XTND}.} Si tenga presente che la chiamata a \func{lseek} non causa
+nessun accesso al file, si limita a modificare la posizione corrente (cioè il
+campo \var{f\_pos} della struttura \kstruct{file}, vedi
+fig.~\ref{fig:file_proc_file}).  Dato che la funzione ritorna la nuova
+posizione, usando il valore zero per \param{offset} si può riottenere la
+posizione corrente nel file con \code{lseek(fd, 0, SEEK\_CUR)}.
 
 \begin{table}[htb]
   \centering
   \footnotesize
-  \begin{tabular}[c]{|l|p{8cm}|}
+  \begin{tabular}[c]{|l|p{10cm}|}
     \hline
     \textbf{Costante} & \textbf{Significato} \\
     \hline
     \hline
-    \const{SEEK\_SET} & Si fa riferimento all'inizio del file: il valore, che 
+    \constd{SEEK\_SET}& Si fa riferimento all'inizio del file: il valore, che 
                         deve essere positivo, di \param{offset} indica
                         direttamente la nuova posizione corrente.\\
-    \const{SEEK\_CUR} & Si fa riferimento alla posizione corrente del file:
+    \constd{SEEK\_CUR}& Si fa riferimento alla posizione corrente del file:
                         ad essa viene sommato \param{offset}, che può essere
                         negativo e positivo, per ottenere la nuova posizione
                         corrente.\\
-    \const{SEEK\_END} & Si fa riferimento alla fine del file: alle dimensioni
+    \constd{SEEK\_END}& Si fa riferimento alla fine del file: alle dimensioni
                         del file viene sommato \param{offset}, che può essere
                         negativo e positivo, per ottenere la nuova posizione
                         corrente.\\
     \hline
-    \const{SEEK\_DATA}& Sposta la posizione nel file sull'inizio del primo
+    \constd{SEEK\_DATA}&Sposta la posizione nel file sull'inizio del primo
                         blocco di dati dopo un \textit{hole} che segue (o
-                        coincide) con la posizione indicata da \param{offset}.\\
-    \const{SEEK\_HOLE}& Sposta la posizione sul file all'inizio del primo
+                        coincide) con la posizione indicata da \param{offset}
+                        (dal kernel 3.1).\\
+    \constd{SEEK\_HOLE}&Sposta la posizione sul file all'inizio del primo
                         \textit{hole} nel file che segue o inizia
-                        con \param{offset}, oppure \param{offset} se questo è
-                        all'interno di un \textit{hole} o alla fine del file
-                        se non ci sono \textit{hole} dopo \param{offset}.\\ 
+                        con \param{offset}, oppure si porta su \param{offset} 
+                        se questo è all'interno di un \textit{hole}, oppure si
+                        porta alla fine del file se non ci sono \textit{hole}
+                        dopo \param{offset} (dal kernel 3.1).\\ 
     \hline
-  \end{tabular}
-  \caption{Possibili valori per l'argomento \param{whence} di \func{lseek}.}
+  \end{tabular}  
+  \caption{Possibili valori per l'argomento \param{whence} di \func{lseek}.} 
   \label{tab:lseek_whence_values}
 \end{table}
 
@@ -778,19 +955,12 @@ costanti riportate in tab.~\ref{tab:lseek_whence_values}.\footnote{per
 % NOTE: per SEEK_HOLE e SEEK_DATA, inclusi nel kernel 3.1, vedi
 % http://lwn.net/Articles/439623/ 
 
-Si tenga presente che la chiamata a \func{lseek} non causa nessun accesso al
-file, si limita a modificare la posizione corrente (cioè il campo \var{f\_pos}
-della struttura \kstruct{file}, vedi fig.~\ref{fig:file_proc_file}).  Dato che
-la funzione ritorna la nuova posizione, usando il valore zero
-per \param{offset} si può riottenere la posizione corrente nel file chiamando
-la funzione con \code{lseek(fd, 0, SEEK\_CUR)}.
-
 Si tenga presente inoltre che usare \const{SEEK\_END} non assicura affatto che
 la successiva scrittura avvenga alla fine del file, infatti se questo è stato
 aperto anche da un altro processo che vi ha scritto, la fine del file può
 essersi spostata, ma noi scriveremo alla posizione impostata in precedenza
-(questa è una potenziale sorgente di \itindex{race~condition} \textit{race
-  condition}, vedi sez.~\ref{sec:file_atomic}).
+(questa è una potenziale sorgente di \textit{race condition}, vedi
+sez.~\ref{sec:file_shared_access}).
 
 Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
 questo caso la funzione ritorna l'errore \errcode{ESPIPE}. Questo, oltre che
@@ -798,33 +968,33 @@ per i tre casi citati nel prototipo, vale anche per tutti quei dispositivi che
 non supportano questa funzione, come ad esempio per i file di
 terminale.\footnote{altri sistemi, usando \const{SEEK\_SET}, in questo caso
   ritornano il numero di caratteri che vi sono stati scritti.} Lo standard
-POSIX però non specifica niente in proposito. Inoltre alcuni
-\index{file!speciali} file speciali, ad esempio \file{/dev/null}, non causano
-un errore ma restituiscono un valore indefinito.
+POSIX però non specifica niente in proposito. Inoltre alcuni file speciali, ad
+esempio \file{/dev/null}, non causano un errore ma restituiscono un valore
+indefinito.
 
 \itindbeg{sparse~file} 
+\index{file!\textit{hole}|(} 
 
 Infine si tenga presente che, come accennato in sez.~\ref{sec:file_file_size},
 con \func{lseek} è possibile impostare una posizione anche oltre la corrente
 fine del file. In tal caso alla successiva scrittura il file sarà esteso a
-partire da detta posizione, ed in questo si ha quella che viene chiamata la
-creazione di un \index{file!\textit{hole}} \textsl{buco} nel file.  Il nome
-deriva dal fatto che nonostante la dimensione del file sia cresciuta in
-seguito alla scrittura effettuata, lo spazio vuoto fra la precedente fine del
-file ed la nuova parte scritta dopo lo spostamento non corrisponde ad una
-allocazione effettiva di spazio su disco, che sarebbe inutile dato che quella
-zona è effettivamente vuota.
+partire da detta posizione, con la creazione di quello che viene chiamato
+``\textsl{buco}'' (in gergo \textit{hole}) nel file.  Il nome deriva dal fatto
+che nonostante la dimensione del file sia cresciuta in seguito alla scrittura
+effettuata, lo spazio vuoto fra la precedente fine del file ed la nuova parte
+scritta dopo lo spostamento non corrisponde ad una allocazione effettiva di
+spazio su disco, che sarebbe inutile dato che quella zona è effettivamente
+vuota.
 
 Questa è una delle caratteristiche specifiche della gestione dei file di un
-sistema unix-like, ed in questo caso si ha appunto quello che in gergo si
-chiama un \index{file!\textit{hole}} \textit{hole} nel file e si dice che il
-file in questione è uno \textit{sparse file}. In sostanza, se si ricorda la
-struttura di un filesystem illustrata in fig.~\ref{fig:file_filesys_detail},
-quello che accade è che nell'\textit{inode} del file viene segnata
-l'allocazione di un blocco di dati a partire dalla nuova posizione, ma non
-viene allocato nulla per le posizioni intermedie; in caso di lettura
-sequenziale del contenuto del file il kernel si accorgerà della presenza del
-buco, e restituirà degli zeri come contenuto di quella parte del file.
+sistema unix-like e si dice che il file in questione è uno \textit{sparse
+  file}. In sostanza, se si ricorda la struttura di un filesystem illustrata
+in fig.~\ref{fig:file_filesys_detail}, quello che accade è che
+nell'\textit{inode} del file viene segnata l'allocazione di un blocco di dati
+a partire dalla nuova posizione, ma non viene allocato nulla per le posizioni
+intermedie; in caso di lettura sequenziale del contenuto del file il kernel si
+accorgerà della presenza del buco, e restituirà degli zeri come contenuto di
+quella parte del file.
 
 Questa funzionalità comporta una delle caratteristiche della gestione dei file
 su Unix che spesso genera più confusione in chi non la conosce, per cui
@@ -846,8 +1016,8 @@ Questo comporta che in generale, fintanto che lo si è scritto sequenzialmente,
 la dimensione di un file sarà più o meno corrispondente alla quantità di
 spazio disco da esso occupato, ma esistono dei casi, come questo in cui ci si
 sposta in una posizione oltre la fine corrente del file, o come quello
-accennato in in sez.~\ref{sec:file_file_size} in cui si estende la dimensione
-di un file con una \func{truncate}, in cui in sostanza di modifica il valore
+accennato in sez.~\ref{sec:file_file_size} in cui si estende la dimensione di
+un file con una \func{truncate}, in cui in sostanza si modifica il valore
 della dimensione di \var{st\_size} senza allocare spazio su disco. Questo
 consente di creare inizialmente file di dimensioni anche molto grandi, senza
 dover occupare da subito dello spazio disco che in realtà sarebbe
@@ -855,13 +1025,38 @@ inutilizzato.
 
 \itindend{sparse~file}
 
-
-\subsection{Le funzioni per la lettura}
+A partire dal kernel 3.1, riprendendo una interfaccia adottata su Solaris,
+sono state aggiunti due nuovi valori per l'argomento \param{whence}, riportati
+nella seconda sezione di tab.~\ref{tab:lseek_whence_values}, che consentono di
+riconoscere la presenza di \textit{hole} all'interno dei file ad uso di quelle
+applicazioni (come i programmi di backup) che possono salvare spazio disco
+nella copia degli \textit{sparse file}. Una applicazione può così determinare
+la presenza di un \textit{hole} usando \const{SEEK\_HOLE} all'inizio del file
+e determinare poi l'inizio della successiva sezione di dati usando
+\const{SEEK\_DATA}. Per compatibilità con i filesystem che non supportano
+questa funzionalità è previsto comunque che in tal caso \const{SEEK\_HOLE}
+riporti sempre la fine del file e \const{SEEK\_DATA} il valore
+di \param{offset}.
+
+Inoltre la decisione di come riportare (o di non riportare) la presenza di un
+buco in un file è lasciata all'implementazione del
+filesystem, dato che esistono vari motivi per cui una sezione di un file può
+non contenere dati ed essere riportata come tale (ad esempio può essere stata
+preallocata con \func{fallocate}, vedi sez.~\ref{sec:file_fadvise}) oltre a
+quelle classiche appena esposte. Questo significa che l'uso di questi nuovi
+valori non garantisce la mappatura della effettiva allocazione dello spazio
+disco di un file, per il quale esiste una specifica operazione di controllo
+(vedi sez.~\ref{sec:file_fcntl_ioctl}).
+
+\index{file!\textit{hole}|)} 
+
+
+\subsection{Le funzioni per la lettura di un file}
 \label{sec:file_read}
 
 Una volta che un file è stato aperto (con il permesso in lettura) si possono
-leggere i dati che contiene utilizzando la funzione \funcd{read}, il cui
-prototipo è:
+leggere i dati che contiene utilizzando la funzione di sistema \funcd{read},
+il cui prototipo è:
 
 \begin{funcproto}{
 \fhead{unistd.h}
@@ -872,37 +1067,29 @@ prototipo è:
 {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{EAGAIN}] la funzione non ha nessun dato da restituire e si è
+    aperto il file con \const{O\_NONBLOCK}.
+  \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+  \item[\errcode{EINVAL}] \param{fd} è associato ad un oggetto non leggibile,
+    o lo si è ottenuto da \func{timerfd\_create} (vedi
+    sez.~\ref{sec:sig_signalfd_eventfd}) e si è usato un valore sbagliato
+    per \param{size} o si è usato \const{O\_DIRECT} ed il buffer non è
+    allineato.
+  \item[\errval{EIO}] si è tentata la lettura dal terminale di controllo
+    essendo in background (vedi sez.~\ref{sec:term_io_design}).
   \end{errlist}
-  ed inoltre 
nel loro significato generico.}
+  ed inoltre \errval{EBADF}, \errval{EFAULT} e \errval{EISDIR}, nel loro
+  significato generico.}
 \end{funcproto}
 
-\begin{prototype}{unistd.h}{ssize\_t read(int fd, void * buf, size\_t count)}
-  
-  Cerca di leggere \param{count} byte dal file \param{fd} al buffer
-  \param{buf}.
-  
-  \bodydesc{La funzione ritorna il numero di byte letti in caso di successo e
-    $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
-  \begin{errlist}
-  \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale prima di
-    aver potuto leggere qualsiasi dato.
-  \item[\errcode{EAGAIN}] la funzione non aveva nessun dato da restituire e si
-    era aperto il file in modalità \const{O\_NONBLOCK}.
-  \end{errlist}
-  ed inoltre \errval{EBADF}, \errval{EIO}, \errval{EISDIR}, \errval{EBADF},
-  \errval{EINVAL} e \errval{EFAULT} ed eventuali altri errori dipendenti dalla
-  natura dell'oggetto connesso a \param{fd}.}
-\end{prototype}
-
-La funzione tenta di leggere \param{count} byte a partire dalla posizione
-corrente nel file. Dopo la lettura la posizione sul file è spostata
-automaticamente in avanti del numero di byte letti. Se \param{count} è zero la
-funzione restituisce zero senza nessun altro risultato.  Si deve sempre tener
-presente che non è detto che la funzione \func{read} restituisca sempre il
+La funzione tenta di leggere \param{count} byte dal file \param{fd} a partire
+dalla posizione corrente, scrivendoli nel buffer \param{buf}. Dopo la lettura
+la posizione sul file è spostata automaticamente in avanti del numero di byte
+letti. Se \param{count} è zero la funzione restituisce zero senza nessun altro
+risultato. Inoltre che non è detto che la funzione \func{read} restituisca il
 numero di byte richiesto, ci sono infatti varie ragioni per cui la funzione
-può restituire un numero di byte inferiore; questo è un comportamento normale,
-e non un errore, che bisogna sempre tenere presente.  
+può restituire un numero di byte inferiore: questo è un comportamento normale,
+e non un errore, che bisogna sempre tenere presente.
 
 La prima e più ovvia di queste ragioni è che si è chiesto di leggere più byte
 di quanto il file ne contenga. In questo caso il file viene letto fino alla
@@ -916,52 +1103,58 @@ continuare a ricevere zero come valore di ritorno.
 
 Con i \textsl{file regolari} questa è l'unica situazione in cui si può avere
 un numero di byte letti inferiore a quello richiesto, ma questo non è vero
-quando si legge da un terminale, da una fifo o da una pipe. In tal caso
-infatti, se non ci sono dati in ingresso, la \func{read} si blocca (a meno di
-non aver selezionato la modalità non bloccante, vedi
-sez.~\ref{sec:file_noblocking}) e ritorna solo quando ne arrivano; se il numero
-di byte richiesti eccede quelli disponibili la funzione ritorna comunque, ma
-con un numero di byte inferiore a quelli richiesti.
+quando si legge da un terminale, da una \textit{fifo} o da una
+\textit{pipe}. In tal caso infatti, se non ci sono dati in ingresso, la
+\func{read} si blocca (a meno di non aver selezionato la modalità non
+bloccante, vedi sez.~\ref{sec:file_noblocking}) e ritorna solo quando ne
+arrivano; se il numero di byte richiesti eccede quelli disponibili la funzione
+ritorna comunque, ma con un numero di byte inferiore a quelli richiesti.
 
 Lo stesso comportamento avviene caso di lettura dalla rete (cioè su un socket,
 come vedremo in sez.~\ref{sec:sock_io_behav}), o per la lettura da certi file
 di dispositivo, come le unità a nastro, che restituiscono sempre i dati ad un
 singolo blocco alla volta, o come le linee seriali, che restituiscono solo i
-dati ricevuti fino al momento della lettura.
+dati ricevuti fino al momento della lettura, o i terminali, per i quali si
+applicano inoltre ulteriori condizioni che approfondiremo in
+sez.~\ref{sec:sess_terminal_io}.
 
 Infine anche le due condizioni segnalate dagli errori \errcode{EINTR} ed
 \errcode{EAGAIN} non sono propriamente degli errori. La prima si verifica
 quando la \func{read} è bloccata in attesa di dati in ingresso e viene
-interrotta da un segnale; in tal caso l'azione da intraprendere è quella di
-rieseguire la funzione.  Torneremo in dettaglio sull'argomento in
+interrotta da un segnale. In tal caso l'azione da intraprendere è quella di
+rieseguire la funzione, torneremo in dettaglio sull'argomento in
 sez.~\ref{sec:sig_gen_beha}.  La seconda si verifica quando il file è aperto
-in modalità non bloccante (vedi sez.~\ref{sec:file_noblocking}) e non ci sono
-dati in ingresso: la funzione allora ritorna immediatamente con un errore
+in modalità non bloccante (con \const{O\_NONBLOCK}) e non ci sono dati in
+ingresso: la funzione allora ritorna immediatamente con un errore
 \errcode{EAGAIN}\footnote{in BSD si usa per questo errore la costante
-  \errcode{EWOULDBLOCK}, in Linux, con le \acr{glibc}, questa è sinonima di
-  \errcode{EAGAIN}.} che indica soltanto che non essendoci al momento dati
-disponibili occorre provare a ripetere la lettura in un secondo tempo.
+  \errcode{EWOULDBLOCK}, in Linux, con la \acr{glibc}, questa è sinonima di
+  \errcode{EAGAIN}, ma se si vuole essere completamente portabili occorre
+  verificare entrambi i valori, dato che POSIX.1-2001 non richiede che siano
+  coincidenti.} che indica soltanto che non essendoci al momento dati
+disponibili occorre provare a ripetere la lettura in un secondo tempo,
+torneremo sull'argomento in sez.~\ref{sec:file_noblocking}.
 
 La funzione \func{read} è una delle \textit{system call} fondamentali,
 esistenti fin dagli albori di Unix, ma nella seconda versione delle
 \textit{Single Unix Specification}\footnote{questa funzione, e l'analoga
-  \func{pwrite} sono state aggiunte nel kernel 2.1.60, il supporto nelle
+  \func{pwrite} sono state aggiunte nel kernel 2.1.60, il supporto nella
   \acr{glibc}, compresa l'emulazione per i vecchi kernel che non hanno la
   \textit{system call}, è stato aggiunto con la versione 2.1, in versioni
   precedenti sia del kernel che delle librerie la funzione non è disponibile.}
 (quello che viene chiamato normalmente Unix98, vedi
 sez.~\ref{sec:intro_xopen}) è stata introdotta la definizione di un'altra
-funzione di lettura, \funcd{pread}, il cui prototipo è:
-\begin{prototype}{unistd.h}
-{ssize\_t pread(int fd, void * buf, size\_t count, off\_t offset)}
-
-Cerca di leggere \param{count} byte dal file \param{fd}, a partire dalla
-posizione \param{offset}, nel buffer \param{buf}.
-  
-\bodydesc{La funzione ritorna il numero di byte letti in caso di successo e
-  $-1$ in caso di errore, nel qual caso \var{errno} assumerà i valori già
-  visti per \func{read} e \func{lseek}.}
-\end{prototype}
+funzione di sistema, \funcd{pread}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{ssize\_t pread(int fd, void * buf, size\_t count, off\_t offset)}
+\fdesc{Legge a partire da una posizione sul file.} 
+}
+
+{La funzione ritorna il numero di byte letti in caso di successo e $-1$ per un
+  errore, nel qual caso \var{errno} assumerà i valori già visti per
+  \func{read} e \func{lseek}.}
+\end{funcproto}
 
 La funzione prende esattamente gli stessi argomenti di \func{read} con lo
 stesso significato, a cui si aggiunge l'argomento \param{offset} che indica
@@ -973,61 +1166,68 @@ L'uso di \func{pread} è equivalente all'esecuzione di una \func{read} seguita
 da una \func{lseek} che riporti al valore precedente la posizione corrente sul
 file, ma permette di eseguire l'operazione atomicamente. Questo può essere
 importante quando la posizione sul file viene condivisa da processi diversi
-(vedi sez.~\ref{sec:file_sharing}).  Il valore di
+(vedi sez.~\ref{sec:file_shared_access}).  Il valore di
 \param{offset} fa sempre riferimento all'inizio del file.
 
 La funzione \func{pread} è disponibile anche in Linux, però diventa
 accessibile solo attivando il supporto delle estensioni previste dalle
 \textit{Single Unix Specification} con la definizione della macro:
-\begin{verbatim}
+\begin{Example}
 #define _XOPEN_SOURCE 500
-\end{verbatim}
+\end{Example}
 e si ricordi di definire questa macro prima dell'inclusione del file di
 dichiarazioni \headfile{unistd.h}.
 
 
 
-\subsection{Le funzioni per la scrittura}
+\subsection{Le funzioni per la scrittura di un file}
 \label{sec:file_write}
 
 Una volta che un file è stato aperto (con il permesso in scrittura) si può
-scrivere su di esso utilizzando la funzione \funcd{write}, il cui prototipo è:
-\begin{prototype}{unistd.h}{ssize\_t write(int fd, void * buf, size\_t count)}
-  
-  Scrive \param{count} byte dal buffer \param{buf} sul file \param{fd}.
-  
-  \bodydesc{La funzione ritorna il numero di byte scritti in caso di successo
-    e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei
-    valori:
+scrivere su di esso utilizzando la funzione di sistema \funcd{write}, il cui
+prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{ssize\_t write(int fd, void * buf, size\_t count)}
+\fdesc{Scrive i dati su un file.} 
+}
+
+{La funzione ritorna il numero di byte scritti in caso di successo e $-1$ per
+  un errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EINVAL}] \param{fd} è connesso ad un oggetto che non consente
-    la scrittura.
+  \item[\errcode{EAGAIN}] ci si sarebbe bloccati, ma il file era aperto in
+    modalità \const{O\_NONBLOCK}.
   \item[\errcode{EFBIG}] si è cercato di scrivere oltre la dimensione massima
     consentita dal filesystem o il limite per le dimensioni dei file del
     processo o su una posizione oltre il massimo consentito.
-  \item[\errcode{EPIPE}] \param{fd} è connesso ad una pipe il cui altro capo è
-    chiuso in lettura; in questo caso viene anche generato il segnale
-    \signal{SIGPIPE}, se questo viene gestito (o bloccato o ignorato) la
-    funzione ritorna questo errore.
   \item[\errcode{EINTR}] si è stati interrotti da un segnale prima di aver
     potuto scrivere qualsiasi dato.
-  \item[\errcode{EAGAIN}] ci si sarebbe bloccati, ma il file era aperto in
-    modalità \const{O\_NONBLOCK}.
+  \item[\errcode{EINVAL}] \param{fd} è connesso ad un oggetto che non consente
+    la scrittura o si è usato \const{O\_DIRECT} ed il buffer non è allineato.
+  \item[\errcode{EPIPE}] \param{fd} è connesso ad una \textit{pipe} il cui
+    altro capo è chiuso in lettura; in questo caso viene anche generato il
+    segnale \signal{SIGPIPE}, se questo viene gestito (o bloccato o ignorato)
+    la funzione ritorna questo errore.
   \end{errlist}
-  ed inoltre \errval{EBADF}, \errval{EIO}, \errval{EISDIR}, \errval{EBADF},
-  \errval{ENOSPC}, \errval{EINVAL} e \errval{EFAULT} ed eventuali altri errori
-  dipendenti dalla natura dell'oggetto connesso a \param{fd}.}
-\end{prototype}
+  ed inoltre \errval{EBADF}, \errval{EFAULT}, \errval{EIO}, \errval{EISDIR},
+  \errval{ENOSPC} nel loro significato generico.}
+\end{funcproto}
+
+
+\itindbeg{append~mode}
 
 Come nel caso di \func{read} la funzione tenta di scrivere \param{count} byte
 a partire dalla posizione corrente nel file e sposta automaticamente la
 posizione in avanti del numero di byte scritti. Se il file è aperto in
-modalità \itindex{append~mode} \const{O\_APPEND} i dati vengono sempre scritti
+modalità \textit{append} con \const{O\_APPEND} i dati vengono sempre scritti
 alla fine del file.  Lo standard POSIX richiede che i dati scritti siano
 immediatamente disponibili ad una \func{read} chiamata dopo che la
 \func{write} che li ha scritti è ritornata; ma dati i meccanismi di caching
 non è detto che tutti i filesystem supportino questa capacità.
 
+\itindend{append~mode}
+
 Se \param{count} è zero la funzione restituisce zero senza fare nient'altro.
 Per i file ordinari il numero di byte scritti è sempre uguale a quello
 indicato da \param{count}, a meno di un errore. Negli altri casi si ha lo
@@ -1036,16 +1236,18 @@ stesso comportamento di \func{read}.
 Anche per \func{write} lo standard Unix98 definisce un'analoga \funcd{pwrite}
 per scrivere alla posizione indicata senza modificare la posizione corrente
 nel file, il suo prototipo è:
-\begin{prototype}{unistd.h}
-{ssize\_t pwrite(int fd, void * buf, size\_t count, off\_t offset)}
-  
-Cerca di scrivere sul file \param{fd}, a partire dalla posizione
-\param{offset}, \param{count} byte dal buffer \param{buf}.
-  
-\bodydesc{La funzione ritorna il numero di byte letti in caso di successo e
-  $-1$ in caso di errore, nel qual caso \var{errno} assumerà i valori già
-  visti per \func{write} e \func{lseek}.}
-\end{prototype}
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{ssize\_t pwrite(int fd, void * buf, size\_t count, off\_t offset)}
+\fdesc{Scrive a partire da una posizione sul file.} 
+}
+
+{La funzione ritorna il numero di byte letti in caso di successo e $-1$ per un
+  errore, nel qual caso \var{errno} assumerà i valori già visti per
+  \func{write} e \func{lseek}.}
+\end{funcproto}
+
 \noindent e per essa valgono le stesse considerazioni fatte per \func{pread}.
 
 
@@ -1059,18 +1261,19 @@ permettono di eseguire alcune operazioni avanzate con i file (il grosso
 dell'argomento sarà comunque affrontato in cap.~\ref{cha:file_advanced}).
 
 
-\subsection{La condivisione dei files}
-\label{sec:file_sharing}
+\subsection{La gestione dell'accesso concorrente ai files}
+\label{sec:file_shared_access}
 
 In sez.~\ref{sec:file_fd} abbiamo descritto brevemente l'architettura
 dell'interfaccia con i file da parte di un processo, mostrando in
 fig.~\ref{fig:file_proc_file} le principali strutture usate dal kernel;
 esamineremo ora in dettaglio le conseguenze che questa architettura ha nei
-confronti dell'accesso allo stesso file da parte di processi diversi.
+confronti dell'accesso concorrente allo stesso file da parte di processi
+diversi.
 
 \begin{figure}[!htb]
   \centering
-  \includegraphics[width=15cm]{img/filemultacc}
+  \includegraphics[width=12cm]{img/filemultacc}
   \caption{Schema dell'accesso allo stesso file da parte di due processi 
     diversi}
   \label{fig:file_mult_acc}
@@ -1081,406 +1284,502 @@ disco; sulla base di quanto visto in sez.~\ref{sec:file_fd} avremo una
 situazione come quella illustrata in fig.~\ref{fig:file_mult_acc}: ciascun
 processo avrà una sua voce nella \textit{file table} referenziata da un
 diverso file descriptor nella sua \kstruct{file\_struct}. Entrambe le voci
-nella \itindex{file~table} \textit{file table} faranno però riferimento allo
-stesso \itindex{inode} inode su disco.
+nella \textit{file table} faranno però riferimento allo stesso \textit{inode}
+su disco.
 
 Questo significa che ciascun processo avrà la sua posizione corrente sul file,
 la sua modalità di accesso e versioni proprie di tutte le proprietà che
-vengono mantenute nella sua voce della \itindex{file~table} \textit{file
-  table}. Questo ha conseguenze specifiche sugli effetti della possibile
-azione simultanea sullo stesso file, in particolare occorre tenere presente
-che:
+vengono mantenute nella sua voce della \textit{file table}. Questo ha
+conseguenze specifiche sugli effetti della possibile azione simultanea sullo
+stesso file, in particolare occorre tenere presente che:
 \begin{itemize}
-\item ciascun processo può scrivere indipendentemente; dopo ciascuna
-  \func{write} la posizione corrente sarà cambiata solo nel processo. Se la
-  scrittura eccede la dimensione corrente del file questo verrà esteso
-  automaticamente con l'aggiornamento del campo \var{i\_size} \itindex{inode}
-  nell'inode.
-\item se un file è in modalità \itindex{append~mode} \const{O\_APPEND} tutte
-  le volte che viene effettuata una scrittura la posizione corrente viene
-  prima impostata alla dimensione corrente del file letta \itindex{inode}
-  dall'inode. Dopo la scrittura il file viene automaticamente esteso.
+\item ciascun processo può scrivere indipendentemente, dopo ciascuna
+  \func{write} la posizione corrente sarà cambiata solo nel processo
+  scrivente. Se la scrittura eccede la dimensione corrente del file questo
+  verrà esteso automaticamente con l'aggiornamento del campo \var{i\_size}
+  della struttura \kstruct{inode}.
+\item se un file è in modalità \const{O\_APPEND} tutte le volte che viene
+  effettuata una scrittura la posizione corrente viene prima impostata alla
+  dimensione corrente del file letta dalla struttura \kstruct{inode}. Dopo la
+  scrittura il file viene automaticamente esteso.
 \item l'effetto di \func{lseek} è solo quello di cambiare il campo
-  \var{f\_pos} nella struttura \kstruct{file} della \itindex{file~table}
-  \textit{file table}, non c'è nessuna operazione sul file su disco. Quando la
-  si usa per porsi alla fine del file la posizione viene impostata leggendo la
-  dimensione corrente \itindex{inode} dall'inode.
+  \var{f\_pos} nella struttura \kstruct{file} della \textit{file table}, non
+  c'è nessuna operazione sul file su disco. Quando la si usa per porsi alla
+  fine del file la posizione viene impostata leggendo la dimensione corrente
+  dalla struttura \kstruct{inode}.
 \end{itemize}
 
 \begin{figure}[!htb]
   \centering
-  \includegraphics[width=15cm]{img/fileshar}
+  \includegraphics[width=12cm]{img/fileshar}
   \caption{Schema dell'accesso ai file da parte di un processo figlio}
   \label{fig:file_acc_child}
 \end{figure}
 
 Il secondo caso è quello in cui due file descriptor di due processi diversi
-puntino alla stessa voce nella \itindex{file~table} \textit{file table};
-questo è ad esempio il caso dei file aperti che vengono ereditati dal processo
-figlio all'esecuzione di una \func{fork} (si ricordi quanto detto in
-sez.~\ref{sec:proc_fork}). La situazione è illustrata in
-fig.~\ref{fig:file_acc_child}; dato che il processo figlio riceve una copia
-dello spazio di indirizzi del padre, riceverà anche una copia di
-\kstruct{file\_struct} e relativa tabella dei file aperti.
-
-In questo modo padre e figlio avranno gli stessi file descriptor che faranno
-riferimento alla stessa voce nella \textit{file table}, condividendo così la
-posizione corrente sul file. Questo ha le conseguenze descritte a suo tempo in
-sez.~\ref{sec:proc_fork}: in caso di scrittura contemporanea la posizione
-corrente nel file varierà per entrambi i processi (in quanto verrà modificato
-\var{f\_pos} che è lo stesso per entrambi).
-
-Si noti inoltre che anche i \itindex{file~status~flag} flag di stato del file
-(quelli impostati dall'argomento \param{flag} di \func{open}) essendo tenuti
-nella voce della \textit{file table}\footnote{per la precisione nel campo
-  \var{f\_flags} di \kstruct{file}, vedi fig.~\ref{fig:kstruct_file}.},
-vengono in questo caso condivisi. Ai file però sono associati anche altri
-flag, dei quali l'unico usato al momento è \const{FD\_CLOEXEC}, detti
-\index{file~descriptor~flags} \textit{file descriptor flags}. Questi ultimi
-sono tenuti invece in \kstruct{file\_struct}, e perciò sono specifici di
+puntino alla stessa voce nella \textit{file table}.  Questo è ad esempio il
+caso dei file aperti che vengono ereditati dal processo figlio all'esecuzione
+di una \func{fork} (si ricordi quanto detto in sez.~\ref{sec:proc_fork}). La
+situazione è illustrata in fig.~\ref{fig:file_acc_child}; dato che il processo
+figlio riceve una copia dello spazio di indirizzi del padre, riceverà anche
+una copia di \kstruct{file\_struct} e della relativa tabella dei file aperti.
+
+Questo significa che il figlio avrà gli stessi file aperti del padre in
+quanto la sua \kstruct{file\_struct}, pur essendo allocata in maniera
+indipendente, contiene gli stessi valori di quella del padre e quindi i suoi
+file descriptor faranno riferimento alla stessa voce nella \textit{file
+  table}, condividendo così la posizione corrente sul file. Questo ha le
+conseguenze descritte a suo tempo in sez.~\ref{sec:proc_fork}: in caso di
+scrittura o lettura da parte di uno dei due processi, la posizione corrente
+nel file varierà per entrambi, in quanto verrà modificato il campo
+\var{f\_pos} della struttura \kstruct{file}, che è la stessa per
+entrambi. Questo consente una sorta di ``\textsl{sincronizzazione}''
+automatica della posizione sul file fra padre e figlio che occorre tenere
+presente.
+
+Si noti inoltre che in questo caso anche i flag di stato del file, essendo
+mantenuti nella struttura \kstruct{file} della \textit{file table}, vengono
+condivisi, per cui una modifica degli stessi con \func{fcntl} (vedi
+sez.~\ref{sec:file_fcntl_ioctl}) si applicherebbe a tutti processi che
+condividono la voce nella \textit{file table}. Ai file però sono associati
+anche altri flag, dei quali l'unico usato al momento è \constd{FD\_CLOEXEC},
+detti \itindex{file~descriptor~flags} \textit{file descriptor flags}; questi
+invece sono mantenuti in \kstruct{file\_struct}, e perciò sono locali per
 ciascun processo e non vengono modificati dalle azioni degli altri anche in
 caso di condivisione della stessa voce della \textit{file table}.
 
-
-
-\subsection{Operazioni atomiche con i file}
-\label{sec:file_atomic}
-
-Come si è visto in un sistema unix-like è sempre possibile per più processi
-accedere in contemporanea allo stesso file, e che le operazioni di lettura e
-scrittura possono essere fatte da ogni processo in maniera autonoma in base
-ad una posizione corrente nel file che è locale a ciascuno di essi.
-
-Se dal punto di vista della lettura dei dati questo non comporta nessun
-problema, quando si andrà a scrivere le operazioni potranno mescolarsi in
-maniera imprevedibile.  Il sistema però fornisce in alcuni casi la possibilità
-di eseguire alcune operazioni di scrittura in maniera coordinata anche senza
-utilizzare meccanismi di sincronizzazione più complessi (come il
-\itindex{file~locking} \textit{file locking}, che esamineremo in
-sez.~\ref{sec:file_locking}).
+Si tenga presente dunque che in un sistema unix-like è sempre possibile per
+più processi accedere in contemporanea allo stesso file e che non esistono, a
+differenza di altri sistemi operativi, dei meccanismi di blocco o di
+restrizione dell'accesso impliciti se più processi vogliono accedere allo
+stesso file. Questo significa che le operazioni di lettura e scrittura vengono
+sempre fatte da ogni processo in maniera autonoma, utilizzando una posizione
+corrente nel file che normalmente (a meno di non trovarsi nella situazione di
+fig.~\ref{fig:file_acc_child}) è locale a ciascuno di essi.
+
+Dal punto di vista della lettura dei dati questo comporta la possibilità di
+poter leggere dati non coerenti in caso di scrittura contemporanea da parte di
+un altro processo. Dal punto di vista della scrittura invece si potranno avere
+sovrapposizioni imprevedibili quando due processi scrivono nella stessa
+sezione di file, dato che ciascuno lo farà in maniera indipendente.  Il
+sistema però fornisce in alcuni casi la possibilità di eseguire alcune
+operazioni di scrittura in maniera coordinata anche senza utilizzare dei
+meccanismi di sincronizzazione espliciti come il \textit{file locking}, che
+esamineremo in sez.~\ref{sec:file_locking}.
 
 Un caso tipico di necessità di accesso condiviso in scrittura è quello in cui
 vari processi devono scrivere alla fine di un file (ad esempio un file di
 log). Come accennato in sez.~\ref{sec:file_lseek} impostare la posizione alla
-fine del file e poi scrivere può condurre ad una \itindex{race~condition}
-\textit{race condition}: infatti può succedere che un secondo processo scriva
-alla fine del file fra la \func{lseek} e la \func{write}; in questo caso, come
-abbiamo appena visto, il file sarà esteso, ma il nostro primo processo avrà
-ancora la posizione corrente impostata con la \func{lseek} che non corrisponde
-più alla fine del file, e la successiva \func{write} sovrascriverà i dati del
-secondo processo.
-
-Il problema è che usare due \textit{system call} in successione non è
-un'operazione atomica; il problema è stato risolto introducendo la modalità
-\itindex{append~mode} \const{O\_APPEND}. In questo caso infatti, come abbiamo
-descritto in precedenza, è il kernel che aggiorna automaticamente la posizione
-alla fine del file prima di effettuare la scrittura, e poi estende il file.
-Tutto questo avviene all'interno di una singola \textit{system call} (la
-\func{write}) che non essendo interrompibile da un altro processo costituisce
-un'operazione atomica.
-
-Un altro caso tipico in cui è necessaria l'atomicità è quello in cui si vuole
-creare un \textsl{file di lock} \index{file!di lock}, bloccandosi se il file
-esiste. In questo caso la sequenza logica porterebbe a verificare prima
-l'esistenza del file con una \func{stat} per poi crearlo con una \func{creat};
-di nuovo avremmo la possibilità di una \itindex{race~condition} \textit{race
-  condition} da parte di un altro processo che crea lo stesso file fra il
-controllo e la creazione.
-
-Per questo motivo sono stati introdotti per \func{open} i due flag
-\const{O\_CREAT} e \const{O\_EXCL}. In questo modo l'operazione di controllo
-dell'esistenza del file (con relativa uscita dalla funzione con un errore) e
-creazione in caso di assenza, diventa atomica essendo svolta tutta all'interno
-di una singola \textit{system call} (per i dettagli sull'uso di questa
-caratteristica si veda sez.~\ref{sec:ipc_file_lock}).
-
-
-\subsection{Le funzioni \func{sync} e \func{fsync}}
-\label{sec:file_sync}
-
-% TODO, aggiungere syncfs, introdotta con il 2.6.39
-
-Come accennato in sez.~\ref{sec:file_close} tutte le operazioni di scrittura
-sono in genere bufferizzate dal kernel, che provvede ad effettuarle in maniera
-asincrona (ad esempio accorpando gli accessi alla stessa zona del disco) in un
-secondo tempo rispetto al momento della esecuzione della \func{write}.
-
-Per questo motivo, quando è necessaria una sincronizzazione dei dati, il
-sistema mette a disposizione delle funzioni che provvedono a forzare lo
-scarico dei dati dai buffer del kernel.\footnote{come già accennato neanche
-  questo dà la garanzia assoluta che i dati siano integri dopo la chiamata,
-  l'hardware dei dischi è in genere dotato di un suo meccanismo interno di
-  ottimizzazione per l'accesso al disco che può ritardare ulteriormente la
-  scrittura effettiva.} La prima di queste funzioni è \funcd{sync} il cui
-prototipo è:
-\begin{prototype}{unistd.h}{int sync(void)}
-  
-  Sincronizza il buffer della cache dei file col disco.
-  
-  \bodydesc{La funzione ritorna sempre zero.}
-\end{prototype}
-\noindent  i vari standard prevedono che la funzione si limiti a far partire
-le operazioni, ritornando immediatamente; in Linux (dal kernel 1.3.20) invece
-la funzione aspetta la conclusione delle operazioni di sincronizzazione del
-kernel.
-
-La funzione viene usata dal comando \cmd{sync} quando si vuole forzare
-esplicitamente lo scarico dei dati su disco, o dal demone di sistema
-\cmd{update} che esegue lo scarico dei dati ad intervalli di tempo fissi: il
-valore tradizionale, usato da BSD, per l'update dei dati è ogni 30 secondi, ma
-in Linux il valore utilizzato è di 5 secondi; con le nuove versioni\footnote{a
-  partire dal kernel 2.2.8} poi, è il kernel che si occupa direttamente di
-tutto quanto attraverso il demone interno \cmd{bdflush}, il cui comportamento
-può essere controllato attraverso il file \sysctlfile{vm/bdflush} (per
-il significato dei valori si può leggere la documentazione allegata al kernel
-in \file{Documentation/sysctl/vm.txt}).
-
-Quando si vogliono scaricare soltanto i dati di un file (ad esempio essere
-sicuri che i dati di un database sono stati registrati su disco) si possono
-usare le due funzioni \funcd{fsync} e \funcd{fdatasync}, i cui prototipi sono:
-\begin{functions}
-  \headdecl{unistd.h}
-  \funcdecl{int fsync(int fd)}
-  Sincronizza dati e meta-dati del file \param{fd}
-  \funcdecl{int fdatasync(int fd)}
-  Sincronizza i dati del file \param{fd}.
-  
-  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
-    errore, nel qual caso \var{errno} assume i valori:
-  \begin{errlist}
-  \item[\errcode{EINVAL}] \param{fd} è un \index{file!speciali} file speciale
-    che non supporta la sincronizzazione.
-  \end{errlist}
-  ed inoltre \errval{EBADF}, \errval{EROFS} e \errval{EIO}.}
-\end{functions}
-
-Entrambe le funzioni forzano la sincronizzazione col disco di tutti i dati del
-file specificato, ed attendono fino alla conclusione delle operazioni;
-\func{fsync} forza anche la sincronizzazione dei meta-dati del file (che
-riguardano sia le modifiche alle tabelle di allocazione dei settori, che gli
-altri dati contenuti \itindex{inode} nell'inode che si leggono con \func{fstat},
-come i tempi del file).
-
-Si tenga presente che questo non comporta la sincronizzazione della
-directory che contiene il file (e scrittura della relativa voce su
-disco) che deve essere effettuata esplicitamente.\footnote{in realtà per
-  il filesystem \acr{ext2}, quando lo si monta con l'opzione \cmd{sync},
-  il kernel provvede anche alla sincronizzazione automatica delle voci
-  delle directory.}
-
-
-\subsection{Le funzioni \func{dup} e \func{dup2}}
+fine del file e poi scrivere può condurre ad una \textit{race condition};
+infatti può succedere che un secondo processo scriva alla fine del file fra la
+\func{lseek} e la \func{write}. In questo caso, come abbiamo appena visto, il
+file sarà esteso, ma il primo processo, avrà una posizione corrente che aveva
+impostato con la \func{lseek} che non corrisponde più alla fine del file, e la
+sua successiva \func{write} sovrascriverà i dati del secondo processo.
+
+Il problema deriva dal fatto che usare due \textit{system call} in successione
+non è mai un'operazione atomica dato che il kernel può interrompere
+l'esecuzione del processo fra le due. Nel caso specifico il problema è stato
+risolto introducendo la modalità di scrittura in \textit{append}, attivabile
+con il flag \const{O\_APPEND}. In questo caso infatti, come abbiamo illustrato
+in sez.~\ref{sec:file_open_close}, è il kernel che aggiorna automaticamente la
+posizione alla fine del file prima di effettuare la scrittura, e poi estende
+il file.  Tutto questo avviene all'interno di una singola \textit{system
+  call}, la \func{write}, che non essendo interrompibile da un altro processo
+realizza un'operazione atomica.
+
+
+\subsection{La duplicazione dei file descriptor}
 \label{sec:file_dup}
 
-Abbiamo già visto in sez.~\ref{sec:file_sharing} come un processo figlio
+Abbiamo già visto in sez.~\ref{sec:file_shared_access} come un processo figlio
 condivida gli stessi file descriptor del padre; è possibile però ottenere un
 comportamento analogo all'interno di uno stesso processo \textit{duplicando}
-un file descriptor. Per far questo si usa la funzione \funcd{dup} il cui
-prototipo è:
-\begin{prototype}{unistd.h}{int dup(int oldfd)}
-  Crea una copia del file descriptor \param{oldfd}.
-  
-  \bodydesc{La funzione ritorna il nuovo file descriptor in caso di successo e
-    $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei
-    valori:
+un file descriptor. Per far questo si usa la funzione di sistema \funcd{dup},
+il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int dup(int oldfd)}
+\fdesc{Crea un file descriptor duplicato.} 
+}
+
+{La funzione ritorna il nuovo file descriptor in caso di successo e $-1$ per
+  un errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
   \item[\errcode{EBADF}] \param{oldfd} non è un file aperto.
   \item[\errcode{EMFILE}] si è raggiunto il numero massimo consentito di file
     descriptor aperti.
-  \end{errlist}}
-\end{prototype}
+  \end{errlist}
+}  
+\end{funcproto}
 
 La funzione ritorna, come \func{open}, il primo file descriptor libero. Il
 file descriptor è una copia esatta del precedente ed entrambi possono essere
 interscambiati nell'uso. Per capire meglio il funzionamento della funzione si
-può fare riferimento a fig.~\ref{fig:file_dup}: l'effetto della funzione è
-semplicemente quello di copiare il valore nella struttura
-\kstruct{file\_struct}, cosicché anche il nuovo file descriptor fa riferimento
-alla stessa voce nella \textit{file table}; per questo si dice che il nuovo
-file descriptor è \textsl{duplicato}, da cui il nome della funzione.
+può fare riferimento a fig.~\ref{fig:file_dup}. L'effetto della funzione è
+semplicemente quello di copiare il valore di un certo file descriptor in
+un altro all'interno della struttura \kstruct{file\_struct}, cosicché anche
+questo faccia riferimento alla stessa voce nella \textit{file table}. Per
+questo motivo si dice che il nuovo file descriptor è ``\textsl{duplicato}'',
+da cui il nome della funzione.
 
 \begin{figure}[!htb]
-  \centering \includegraphics[width=14cm]{img/filedup}
+  \centering \includegraphics[width=12cm]{img/filedup}
   \caption{Schema dell'accesso ai file duplicati}
   \label{fig:file_dup}
 \end{figure}
 
 Si noti che per quanto illustrato in fig.~\ref{fig:file_dup} i file descriptor
-duplicati condivideranno eventuali lock, \textit{file status flag}, e
-posizione corrente. Se ad esempio si esegue una \func{lseek} per modificare la
-posizione su uno dei due file descriptor, essa risulterà modificata anche
-sull'altro (dato che quello che viene modificato è lo stesso campo nella voce
-della \textit{file table} a cui entrambi fanno riferimento). L'unica
-differenza fra due file descriptor duplicati è che ciascuno avrà il suo
-\textit{file descriptor flag}; a questo proposito va specificato che nel caso
-di \func{dup} il flag di \textit{close-on-exec} \itindex{close-on-exec} (vedi
-sez.~\ref{sec:proc_exec} e sez.~\ref{sec:file_fcntl}) viene sempre cancellato
-nella copia.
-
-L'uso principale di questa funzione è per la redirezione dell'input e
-dell'output fra l'esecuzione di una \func{fork} e la successiva \func{exec};
-diventa così possibile associare un file (o una pipe) allo standard input o
-allo standard output (torneremo sull'argomento in sez.~\ref{sec:ipc_pipe_use},
-quando tratteremo le pipe). Per fare questo in genere occorre prima chiudere
-il file che si vuole sostituire, cosicché il suo file descriptor possa esser
-restituito alla chiamata di \func{dup}, come primo file descriptor
-disponibile.
-
-Dato che questa è l'operazione più comune, è prevista una diversa versione
-della funzione, \funcd{dup2}, che permette di specificare esplicitamente
-qual è il valore di file descriptor che si vuole avere come duplicato; il suo
-prototipo è:
-\begin{prototype}{unistd.h}{int dup2(int oldfd, int newfd)}
-  
-  Rende \param{newfd} una copia del file descriptor \param{oldfd}.
-  
-  \bodydesc{La funzione ritorna il nuovo file descriptor in caso di successo e
-    $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
+duplicati condivideranno eventuali lock (vedi sez.~\ref{sec:file_locking}), i
+flag di stato, e la posizione corrente sul file. Se ad esempio si esegue una
+\func{lseek} per modificare la posizione su uno dei due file descriptor, essa
+risulterà modificata anche sull'altro, dato che quello che viene modificato è
+lo stesso campo nella voce della \textit{file table} a cui entrambi fanno
+riferimento.
+
+L'unica differenza fra due file descriptor duplicati è che ciascuno avrà un
+suo \textit{file descriptor flag} indipendente. A questo proposito deve essere
+tenuto presente che nel caso in cui si usi \func{dup} per duplicare un file
+descriptor, se questo ha il flag di \textit{close-on-exec} attivo (vedi
+sez.~\ref{sec:proc_exec} e sez.~\ref{sec:file_fcntl_ioctl}), questo verrà
+cancellato nel file descriptor restituito come copia.
+
+L'uso principale di questa funzione è nella shell per la redirezione dei file
+standard di tab.~\ref{tab:file_std_files} fra l'esecuzione di una \func{fork}
+e la successiva \func{exec}. Diventa così possibile associare un file (o una
+\textit{pipe}) allo \textit{standard input} o allo \textit{standard output}
+(vedremo un esempio in sez.~\ref{sec:ipc_pipe_use}, quando tratteremo le
+\textit{pipe}).
+
+Ci si può chiedere perché non sia in questo caso sufficiente chiudere il file
+standard che si vuole redirigere e poi aprire direttamente con \func{open} il
+file vi si vuole far corrispondere, invece di duplicare un file descriptor che
+si è già aperto. La risposta sta nel fatto che il file che si vuole redirigere
+non è detto sia un file regolare, ma potrebbe essere, come accennato, anche
+una \textit{fifo} o un socket, oppure potrebbe essere un file associato ad un file
+descriptor che si è ereditato già aperto (ad esempio attraverso un'altra
+\func{exec}) da un processo antenato del padre, del quale non si conosce il
+nome. Operando direttamente con i file descriptor \func{dup} consente di
+ignorare le origini del file descriptor che si duplica e funziona in maniera
+generica indipendentemente dall'oggetto a cui questo fa riferimento.
+
+Per ottenere la redirezione occorre pertanto disporre del file descriptor
+associato al file che si vuole usare e chiudere il file descriptor che si
+vuole sostituire, cosicché esso possa esser restituito alla successiva
+chiamata di \func{dup} come primo file descriptor disponibile.  Dato che
+questa è l'operazione più comune, è prevista un'altra funzione di sistema,
+\funcd{dup2}, che permette di specificare esplicitamente qual è il numero di
+file descriptor che si vuole ottenere come duplicato; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int dup2(int oldfd, int newfd)}
+\fdesc{Duplica un file descriptor su un altro.} 
+}
+
+{La funzione ritorna il nuovo file descriptor in caso di successo e $-1$ per
+  un errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
   \item[\errcode{EBADF}] \param{oldfd} non è un file aperto o \param{newfd} ha
     un valore fuori dall'intervallo consentito per i file descriptor.
+  \item[\errcode{EBUSY}] si è rilevata la possibilità di una \textit{race
+      condition}.
+  \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
   \item[\errcode{EMFILE}] si è raggiunto il numero massimo consentito di file
     descriptor aperti.
-  \end{errlist}}
-\end{prototype}
-\noindent e qualora il file descriptor \param{newfd} sia già aperto (come
-avviene ad esempio nel caso della duplicazione di uno dei file standard) esso
-sarà prima chiuso e poi duplicato (così che il file duplicato sarà connesso
-allo stesso valore per il file descriptor).
+  \end{errlist}
+}  
+\end{funcproto}
+
+La funzione duplica il file descriptor \param{oldfd} su un altro file
+descriptor di valore \param{newfd}. Qualora il file descriptor \param{newfd}
+sia già aperto, come avviene ad esempio nel caso della duplicazione di uno dei
+file standard di tab.~\ref{tab:file_std_files}, esso sarà prima chiuso e poi
+duplicato. Se \param{newfd} è uguale a \param{oldfd} la funzione non fa nulla
+e si limita a restituire \param{newfd}.
+
+L'uso di \func{dup2} ha vari vantaggi rispetto alla combinazione di
+\func{close} e \func{dup}; anzitutto se \param{oldfd} è uguale \param{newfd}
+questo verrebbe chiuso e \func{dup} fallirebbe, ma soprattutto l'operazione è
+atomica e consente di evitare una \textit{race condition} in cui dopo la
+chiusura del file si potrebbe avere la ricezione di un segnale il cui gestore
+(vedi sez.~\ref{sec:sig_signal_handler}) potrebbe a sua volta aprire un file,
+per cui alla fine \func{dup} restituirebbe un file descriptor diverso da
+quello voluto.
+
+Con Linux inoltre la funzione prevede la possibilità di restituire l'errore
+\errcode{EBUSY}, che non è previsto dallo standard, quando viene rilevata la
+possibilità di una \textit{race condition} interna in cui si cerca di
+duplicare un file descriptor che è stato allocato ma per il quale non sono
+state completate le operazioni di apertura.\footnote{la condizione è
+  abbastanza peculiare e non attinente al tipo di utilizzo indicato, quanto
+  piuttosto ad un eventuale tentativo di duplicare file descriptor non ancora
+  aperti, la condizione di errore non è prevista dallo standard, ma in
+  condizioni simili FreeBSD risponde con un errore di \errval{EBADF}, mentre
+  OpenBSD elimina la possibilità di una \textit{race condition} al costo di
+  una perdita di prestazioni.} In tal caso occorre ritentare l'operazione.
 
 La duplicazione dei file descriptor può essere effettuata anche usando la
 funzione di controllo dei file \func{fcntl} (che esamineremo in
-sez.~\ref{sec:file_fcntl}) con il parametro \const{F\_DUPFD}.  L'operazione ha
-la sintassi \code{fcntl(oldfd, F\_DUPFD, newfd)} e se si usa 0 come valore per
-\param{newfd} diventa equivalente a \func{dup}. 
+sez.~\ref{sec:file_fcntl_ioctl}) con il parametro \const{F\_DUPFD}.
+L'operazione ha la sintassi \code{fcntl(oldfd, F\_DUPFD, newfd)} e se si usa 0
+come valore per \param{newfd} diventa equivalente a \func{dup}.  La sola
+differenza fra le due funzioni (a parte la sintassi ed i diversi codici di
+errore) è che \func{dup2} chiude il file descriptor \param{newfd} se questo è
+già aperto, garantendo che la duplicazione sia effettuata esattamente su di
+esso, invece \func{fcntl} restituisce il primo file descriptor libero di
+valore uguale o maggiore di \param{newfd}, per cui se \param{newfd} è aperto
+la duplicazione avverrà su un altro file descriptor.
+
+Su Linux inoltre è presente una terza funzione di sistema non
+standard,\footnote{la funzione è stata introdotta con il kernel 2.6.27 e resa
+  disponibile con la \acr{glibc} 2.9.} \funcd{dup3}, che consente di duplicare
+un file descriptor reimpostandone i flag, per usarla occorre definire la macro
+\macro{\_GNU\_SOURCE} ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int dup3(int oldfd, int newfd, int flags)}
+\fdesc{Duplica un file descriptor su un altro.} 
+}
+
+{La funzione ritorna il nuovo file descriptor in caso di successo e $-1$ per
+  un errore, nel qual caso \var{errno} assumerà gli stessi valori di
+  \func{dup2} più \errcode{EINVAL} qualora \param{flags} contenga un valore
+  non valido o \param{newfd} sia uguale a \param{oldfd}.
+}  
+\end{funcproto}
+
+La funzione è identica a \func{dup2} ma prevede la possibilità di mantenere il
+flag di \textit{close-on-exec} sul nuovo file descriptor specificando
+\const{O\_CLOEXEC} in \param{flags} (che è l'unico flag usabile in questo
+caso). Inoltre rileva esplicitamente la possibile coincidenza
+fra \param{newfd} e \param{oldfd}, fallendo con un errore di \errval{EINVAL}.
+
+
+\subsection{Le funzioni di sincronizzazione dei dati}
+\label{sec:file_sync}
+
+Come accennato in sez.~\ref{sec:file_open_close} tutte le operazioni di
+scrittura sono in genere bufferizzate dal kernel, che provvede ad effettuarle
+in maniera asincrona, ad esempio accorpando gli accessi alla stessa zona del
+disco, in un secondo tempo rispetto al momento della esecuzione della
+\func{write}.
+
+Per questo motivo quando è necessaria una sincronizzazione dei dati il sistema
+mette a disposizione delle funzioni che provvedono a forzare lo scarico dei
+dati dai buffer del kernel.  La prima di queste funzioni di sistema è
+\funcd{sync}, il cui prototipo è:\footnote{questo è il prototipo usato a
+  partire dalla \acr{glibc} 2.2.2 seguendo gli standard, in precedenza la
+  funzione era definita come \code{int sync(void)} e ritornava sempre $0$.}
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{void sync(void)}
+\fdesc{Sincronizza il buffer della cache dei file col disco.} 
+}
+
+{La funzione non ritorna nulla e non prevede condizioni di errore.}  
+\end{funcproto}
+
+I vari standard prevedono che la funzione si limiti a far partire le
+operazioni, ritornando immediatamente, con Linux fin dal kernel 1.3.20 invece
+la funzione aspetta la conclusione delle operazioni di sincronizzazione. Si
+tenga presente comunque che questo non dà la garanzia assoluta che i dati
+siano integri dopo la chiamata, l'hardware dei dischi è in genere dotato di un
+suo meccanismo interno di bufferizzazione che può ritardare ulteriormente la
+scrittura effettiva.
+
+La funzione viene usata dal comando \cmd{sync} quando si vuole forzare
+esplicitamente lo scarico dei dati su disco, un tempo era invocata da un
+apposito demone di sistema (in genere chiamato \cmd{update}) che eseguiva lo
+scarico dei dati ad intervalli di tempo fissi.  Con le nuove versioni del
+kernel queste operazioni vengono gestite direttamente dal sistema della
+memoria virtuale, attraverso opportuni \textit{task} interni al kernel il cui
+comportamento può essere controllato attraverso il file
+\sysctlfiled{vm/bdflush}.\footnote{per il significato dei valori che si possono
+  scrivere in questo file si consulti la documentazione allegata ai sorgenti
+  del kernel nel file \file{Documentation/sysctl/vm.txt}, trattandosi di
+  argomenti di natura sistemistica non li prenderemo in esame.} Si tenga
+presente che la funzione di sistema \funcm{bdflush}, che un tempo veniva usata
+per queste impostazioni, è deprecata e causa semplicemente la stampa di un
+messaggio nei log del kernel, pertanto non la prenderemo in esame.
+
+Quando si vogliano scaricare i dati di un singolo file, ad esempio essere
+sicuri che i dati di un database siano stati registrati su disco, si possono
+usare le due funzioni di sistema \funcd{fsync} e \funcd{fdatasync}, i cui
+prototipi sono:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int fsync(int fd)}
+\fdesc{Sincronizza dati e metadati di un file.} 
+\fdecl{int fdatasync(int fd)}
+\fdesc{Sincronizza i dati 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{EINVAL}] \param{fd} è un file speciale che non supporta la
+    sincronizzazione.
+  \end{errlist}
+  ed inoltre \errval{EBADF}, \errval{EIO} e \errval{EROFS} nel loro
+  significato generico.}
+\end{funcproto}
 
-La sola differenza fra le due funzioni\footnote{a parte la sintassi ed i
-  diversi codici di errore.} è che \func{dup2} chiude il file descriptor
-\param{newfd} se questo è già aperto, garantendo che la duplicazione sia
-effettuata esattamente su di esso, invece \func{fcntl} restituisce il primo
-file descriptor libero di valore uguale o maggiore di \param{newfd} (e se
-\param{newfd} è aperto la duplicazione avverrà su un altro file descriptor).
+Entrambe le funzioni forzano la sincronizzazione col disco di tutti i dati del
+file specificato, ed attendono fino alla conclusione delle operazioni. La
+prima, \func{fsync} forza anche la sincronizzazione dei meta-dati del file,
+che riguardano sia le modifiche alle tabelle di allocazione dei settori, che
+gli altri dati contenuti nell'\textit{inode} che si leggono con \func{fstat},
+come i tempi del file. Se lo scopo dell'operazione, come avviene spesso per i
+database, è assicurarsi che i dati raggiungano il disco e siano rileggibili
+immediatamente in maniera corretta, è sufficiente l'uso di \func{fdatasync}
+che non comporta anche l'esecuzione di operazioni non necessarie all'integrità
+dei dati, come l'aggiornamento dei tempi di ultima modifica ed ultimo accesso.
+
+Si tenga presente che l'uso di queste funzioni non comporta la
+sincronizzazione della directory che contiene il file e la scrittura della
+relativa voce su disco, che se necessaria deve essere effettuata
+esplicitamente con \func{fsync} sul file descriptor della
+directory.\footnote{in realtà per il filesystem \acr{ext2}, quando lo si monta
+  con l'opzione \cmd{sync}, il kernel provvede anche alla sincronizzazione
+  automatica delle voci delle directory.}
+
+L'uso di \func{sync} presenta in certi casi, quando ci sono più filesystem
+montati, problemi di prestazioni dovute al fatto che la funzione provoca la
+sincronizzazione dei dati su tutti quanti i filesystem, anche quando
+interesserebbe che questo avvenga soltanto su quello dei file su cui si sta
+lavorando, se i dati in attesa sono molti questo può causare seri problemi di
+prestazioni. 
+
+Per questo motivo è stata introdotta una nuova funzione di sistema,
+\funcd{syncfs},\footnote{la funzione è stata introdotta a partire dal kernel
+  2.6.39 ed è accessibile solo se è definita la macro \macro{\_GNU\_SOURCE}, è
+  specifica di Linux e non prevista da nessuno standard.} che effettua lo
+scarico dei dati soltanto per il filesystem su cui si sta operando, il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int syncfs(int fd)}
+\fdesc{Sincronizza il buffer della cache dei file del singolo filesystem col
+  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{EBADF}] \param{fd} non è un descrittore valido.
+  \end{errlist}
+}  
+\end{funcproto}
 
+La funzione richiede che si specifichi nell'argomento \param{fd} un file
+descriptor su cui si sta operando, e lo scarico dei dati sarà limitato al
+filesystem su cui il file ad esso corrispondente si trova.
 
 
-\subsection{Le funzioni \func{openat}, \func{mkdirat} e affini}
+\subsection{Le \textit{at-functions}: \func{openat} e affini}
 \label{sec:file_openat}
 
 \itindbeg{at-functions}
 
-Un problema che si pone con l'uso della funzione \func{open}, così come per
-molte altre funzioni che accettano come argomenti dei
-\itindsub{pathname}{relativo} \textit{pathname} relativi, è che, quando un
-\textit{pathname} relativo non fa riferimento alla \index{directory~di~lavoro}
-directory di lavoro corrente, è possibile che alcuni dei suoi componenti
-vengano modificati in parallelo alla chiamata a \func{open}, e questo lascia
-aperta la possibilità di una \itindex{race~condition} \textit{race condition}.
-
-Inoltre come già accennato, la \index{directory~di~lavoro} directory di lavoro
-corrente è una proprietà del singolo processo; questo significa che quando si
-lavora con i \itindex{thread} \textit{thread} essa sarà la stessa per tutti,
-ma esistono molti casi in cui sarebbe invece utile che ogni singolo
-\itindex{thread} \textit{thread} avesse la sua \index{directory~di~lavoro}
-directory di lavoro.
+Un problema generale che si pone con l'uso della funzione \func{open}, così
+come per le altre funzioni che prendono come argomenti dei \textit{pathname}
+relativi, è la possibilità, quando un \textit{pathname} relativo non fa
+riferimento ad un file posto direttamente nella directory di lavoro corrente,
+che alcuni dei componenti del \textit{pathname} vengano modificati in
+parallelo alla chiamata a \func{open}, cosa che lascia aperta la possibilità
+di una \textit{race condition} in cui c'è spazio per un \textit{symlink
+  attack} (si ricordi quanto visto per \func{access} in
+sez.~\ref{sec:file_perm_management}).
+
+Inoltre come già accennato, la directory di lavoro corrente è una proprietà
+del singolo processo; questo significa che quando si lavora con i
+\textit{thread} essa sarà la stessa per tutti, ma esistono molti casi in cui
+sarebbe invece utile che ogni singolo \textit{thread} avesse la sua directory
+di lavoro.
 
 Per risolvere questi problemi, riprendendo una interfaccia già presente in
 Solaris, a fianco delle normali funzioni che operano sui file (come
 \func{open}, \func{mkdir}, ecc.) sono state introdotte delle ulteriori
-funzioni, dette anche funzioni ``\textit{at}'' in quanto contraddistinte dal
+funzioni, dette anche ``\textit{at-functions}'' in quanto contraddistinte dal
 suffisso \texttt{at}, che permettono l'apertura di un file (o le rispettive
-altre operazioni) usando un \itindsub{pathname}{relativo} \textit{pathname}
-relativo ad una directory specificata.\footnote{l'introduzione è avvenuta su
-  proposta dello sviluppatore principale delle \acr{glibc} Urlich Drepper; le
-  corrispondenti \textit{system call} sono state inserite nel kernel ufficiale
-  a partire dalla versione 2.6.16, in precedenza era disponibile una
-  emulazione che, sia pure con prestazioni inferiori, funzionava facendo
-  ricorso all'uso del filesystem \textit{proc} con l'apertura del file
-  attraverso il riferimento a \textit{pathname} del tipo di
-  \texttt{/proc/self/fd/dirfd/relative\_path}.} Benché queste funzioni non
-siano presenti negli standard tradizionali esse sono state adottate da vari
-Unix\footnote{oltre a Linux e Solaris sono presenti in vari BSD.} fino ad
-essere incluse nella recente revisione (la POSIX.1-2008) dello standard
-POSIX.1; con le \acr{glibc} per l'accesso a queste funzioni è necessario
+altre operazioni) usando un \textit{pathname} relativo ad una directory
+specificata.\footnote{l'introduzione è avvenuta su proposta dello sviluppatore
+  principale della \acr{glibc} Urlich Drepper e le corrispondenti
+  \textit{system call} sono state inserite nel kernel a partire dalla versione
+  2.6.16, in precedenza era disponibile una emulazione che, sia pure con
+  prestazioni inferiori, funzionava facendo ricorso all'uso del filesystem
+  \textit{proc} con l'apertura del file attraverso il riferimento a
+  \textit{pathname} del tipo di \texttt{/proc/self/fd/dirfd/relative\_path}.}
+Benché queste funzioni non siano presenti negli standard tradizionali esse
+sono state adottate da altri sistemi unix-like come Solaris, i vari BSD, fino
+ad essere incluse in una recente revisione (la POSIX.1-2008) dello standard
+POSIX.1. Con la \acr{glibc} per l'accesso a queste funzioni è necessario
 definire la macro \macro{\_ATFILE\_SOURCE}.
 
 L'uso di queste funzioni prevede una apertura iniziale della directory che
-sarà la base della risoluzione dei \itindsub{pathname}{relativo}
-\textit{pathname} relativi che verranno usati in seguito, dopo di che si dovrà
-passare il relativo file descriptor alle varie funzioni che useranno quella
-directory come punto di partenza per la risoluzione.\footnote{in questo modo,
-  anche quando si lavora con i \itindex{thread} \textit{thread}, si può
-  mantenere una \index{directory~di~lavoro} directory di lavoro diversa per
-  ciascuno di essi.}
-
-Questo metodo, oltre a risolvere i problemi di \itindex{race~condition}
-\textit{race condition}, consente anche di ottenere aumenti di prestazioni
-significativi quando si devono eseguire molte operazioni su sezioni
-dell'albero dei file che prevedono delle gerarchie di sottodirectory molto
-profonde; infatti in questo caso basta eseguire la risoluzione del
-\textit{pathname} della directory di partenza una sola volta (nell'apertura
-iniziale) e non tutte le volte che si deve accedere a ciascun file che essa
-contiene.
+sarà la base della risoluzione dei \textit{pathname} relativi che verranno
+usati in seguito, dopo di che si dovrà passare il relativo file descriptor
+alle varie funzioni che useranno quella directory come punto di partenza per
+la risoluzione. In questo modo, anche quando si lavora con i \textit{thread},
+si può mantenere una directory di lavoro diversa per ciascuno di essi.
+
+Questo metodo, oltre a risolvere i problemi di \textit{race condition},
+consente anche di ottenere aumenti di prestazioni significativi quando si
+devono eseguire molte operazioni su sezioni dell'albero dei file che prevedono
+delle gerarchie di sottodirectory molto profonde. Infatti in questo caso basta
+eseguire la risoluzione del \textit{pathname} della directory di partenza una
+sola volta (nell'apertura iniziale) e non tutte le volte che si deve accedere
+a ciascun file che essa contiene.
 
 La sintassi generale di queste nuove funzioni è che esse prevedono come primo
-argomento il file descriptor della directory da usare come base, mentre gli
-argomenti successivi restano identici a quelli della corrispondente funzione
-ordinaria; ad esempio nel caso di \funcd{openat} avremo che essa è definita
-come:
-\begin{functions}
-  \headdecl{fcntl.h}
-  \funcdecl{int openat(int dirfd, const char *pathname, int flags)}
-  \funcdecl{int openat(int dirfd, const char *pathname, int flags,  mode\_t
-    mode))} 
-
-  Apre un file usando come directory di \index{directory~di~lavoro} lavoro
-  corrente \param{dirfd}.
-  
-  \bodydesc{la funzione restituisce gli stessi valori e gli stessi codici di
-    errore di \func{open}, ed in più:
+argomento il file descriptor della directory da usare come base per la
+risoluzione dei nomi, mentre gli argomenti successivi restano identici a
+quelli della corrispondente funzione ordinaria. Se ad esempio prendiamo in
+esame la nuova funzione di sistema \funcd{openat}, avremo il prototipo:
+
+\begin{funcproto}{
+\fhead{fcntl.h}
+\fdecl{int openat(int dirfd, const char *pathname, int flags)}
+\fdecl{int openat(int dirfd, const char *pathname, int flags, mode\_t mode)}
+\fdesc{Apre un file a partire da una directory di lavoro.} 
+}
+
+{La funzione ritorna gli stessi valori e gli stessi codici di errore di
+  \func{open}, ed in più:
   \begin{errlist}
   \item[\errcode{EBADF}] \param{dirfd} non è un file descriptor valido.
-  \item[\errcode{ENOTDIR}] \param{pathname} è un \itindsub{pathname}{relativo}
-    \textit{pathname} relativo, ma
-    \param{dirfd} fa riferimento ad un file. 
-  \end{errlist}}
-\end{functions}
+  \item[\errcode{ENOTDIR}] \param{pathname} è un \textit{pathname} relativo,
+    ma \param{dirfd} fa riferimento ad un file.
+   \end{errlist}
+}  
+\end{funcproto}
 
 Il comportamento delle nuove funzioni è del tutto analogo a quello delle
 corrispettive classiche, con la sola eccezione del fatto che se fra i loro
-argomenti si utilizza un \itindsub{pathname}{relativo} \textit{pathname}
-relativo questo sarà risolto rispetto alla directory indicata
-da \param{dirfd}; qualora invece si usi un \itindsub{pathname}{assoluto}
+argomenti si utilizza un \textit{pathname} relativo questo sarà risolto
+rispetto alla directory indicata da \param{dirfd}. Qualora invece si usi un
 \textit{pathname} assoluto \param{dirfd} verrà semplicemente ignorato. Infine
-se per
-\param{dirfd} si usa il valore speciale \const{AT\_FDCWD},\footnote{questa,
-  come le altre costanti \texttt{AT\_*}, è definita in \headfile{fcntl.h},
-  pertanto se la si vuole usare occorrerà includere comunque questo file,
-  anche per le funzioni che non sono definite in esso.} la risoluzione sarà
-effettuata rispetto alla directory di \index{directory~di~lavoro} lavoro
-corrente del processo.
+se per \param{dirfd} si usa il valore speciale \constd{AT\_FDCWD}, la
+risoluzione sarà effettuata rispetto alla directory di lavoro corrente del
+processo. Si tenga presente però che questa, come le altre costanti
+\texttt{AT\_*}, è definita in \headfile{fcntl.h}, pertanto se la si vuole
+usare occorrerà includere comunque questo file, anche per le funzioni che non
+sono definite in esso.
 
 Così come il comportamento, anche i valori di ritorno e le condizioni di
 errore delle nuove funzioni sono gli stessi delle funzioni classiche, agli
 errori si aggiungono però quelli dovuti a valori errati per \param{dirfd}; in
 particolare si avrà un errore di \errcode{EBADF} se esso non è un file
 descriptor valido, ed un errore di \errcode{ENOTDIR} se esso non fa
-riferimento ad una directory.\footnote{tranne il caso in cui si sia
-  specificato un \itindsub{pathname}{assoluto} \textit{pathname} assoluto, nel
-  qual caso, come detto, il valore di \param{dirfd} sarà completamente
-  ignorato.}
-
-In tab.~\ref{tab:file_atfunc_corr} si sono riportate le funzioni introdotte
-con questa nuova interfaccia, con a fianco la corrispondente funzione
-classica.\footnote{in realtà, come visto in sez.~\ref{sec:file_temp_file}, le
-  funzioni \func{utimes} e \func{lutimes} non sono propriamente le
-  corrispondenti di \func{utimensat}, dato che questa ha una maggiore
-  precisione nella indicazione dei tempi dei file.} La gran parte di queste
-seguono la convenzione appena vista per \func{openat}, in cui agli argomenti
-della corrispondente funzione classica viene anteposto
-l'argomento \param{dirfd}.\footnote{non staremo pertanto a riportarle una per
-  una.} Per una parte di queste, indicate dal contenuto della omonima colonna
-di tab.~\ref{tab:file_atfunc_corr}, oltre al nuovo argomento iniziale, è
-prevista anche l'aggiunta di un ulteriore argomento finale, \param{flags}.
+riferimento ad una directory, tranne il caso in cui si sia specificato un
+\textit{pathname} assoluto, nel qual caso, come detto, il valore
+di \param{dirfd} sarà completamente ignorato.
 
 \begin{table}[htb]
   \centering
@@ -1491,9 +1790,9 @@ prevista anche l'aggiunta di un ulteriore argomento finale, \param{flags}.
     \hline
     \hline
      \func{faccessat} &$\bullet$&\func{access}  \\
-     \func{fchmodat}  &$\bullet$&\func{chmod}   \\
+     \funcm{fchmodat} &$\bullet$&\func{chmod}   \\
      \func{fchownat}  &$\bullet$&\func{chown},\func{lchown}\\
-     \func{fstatat}   &$\bullet$&\func{stat},\func{lstat}  \\
+     \funcm{fstatat}  &$\bullet$&\func{stat},\func{lstat}  \\
      \func{utimensat} &$\bullet$&\func{utimes},\func{lutimes}\\
      \func{linkat}    &$\bullet$\footnotemark&\func{link}    \\
      \funcm{mkdirat}  & --      &\func{mkdir}   \\
@@ -1514,10 +1813,38 @@ prevista anche l'aggiunta di un ulteriore argomento finale, \param{flags}.
 \footnotetext{in questo caso l'argomento \param{flags} è disponibile ed
   utilizzabile solo a partire dal kernel 2.6.18.}
 
-% TODO manca prototipo di fchmodat, verificare se metterlo o metter menzione
-% TODO manca prototipo di fstatat, verificare se metterlo o metter menzione
+In tab.~\ref{tab:file_atfunc_corr} si sono riportate le funzioni introdotte
+con questa nuova interfaccia, con a fianco la corrispondente funzione
+classica. La gran parte di queste seguono la convenzione appena vista per
+\func{openat}, in cui agli argomenti della corrispondente funzione classica
+viene anteposto l'argomento \param{dirfd}, ed hanno per il resto un
+comportamento identico e non staremo pertanto a trattarle una per una. Per una
+parte di queste, indicate dal contenuto della omonima colonna di
+tab.~\ref{tab:file_atfunc_corr}, oltre al nuovo argomento iniziale, è prevista
+anche l'aggiunta di un ulteriore argomento finale, \param{flags}.
+
+
+
+
+% TODO trattare fstatat e con essa
+% TODO trattare anche statx, aggiunta con il kernel 4.11 (vedi
+% https://lwn.net/Articles/707602/ e
+% https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a528d35e8bfcc521d7cb70aaf03e1bd296c8493f) 
+
 % TODO manca prototipo di linkat, verificare se metterlo o metter menzione
+% altre modifiche al riguardo nel 3.11 (AT_EMPTY_PATH?) vedi
+% http://lwn.net/Articles/562488/
+
+% TODO: Trattare esempio di inzializzazione di file e successivo collegamento
+% con l'uso di O_TMPFILE e linkat, vedi man open
+
+
 % TODO manca prototipo di utimensat, verificare se metterlo o metter menzione
+% TODO manca prototipo di renameat2, introdotta nel 3.15, vedi
+% http://lwn.net/Articles/569134/ 
+% TODO manca prototipo di execveat, introdotta nel 3.19, vedi
+% https://lwn.net/Articles/626150/ cerca anche fexecve
+
 
 Per tutte le funzioni che lo prevedono, a parte \func{unlinkat} e
 \funcd{faccessat}, l'ulteriore argomento è stato introdotto solo per fornire
@@ -1532,342 +1859,658 @@ binaria, ed impostato usando i valori delle appropriate costanti
 Come esempio di questo secondo tipo di funzioni possiamo considerare
 \funcd{fchownat}, che può essere usata per sostituire sia \func{chown}
 che \func{lchown}; il suo prototipo è:
-\begin{functions}
-  \headdecl{unistd.h} \headdecl{fcntl.h} 
 
-  \funcdecl{int fchownat(int dirfd, const char *pathname, uid\_t owner, gid\_t
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{fcntl.h} 
+\fdecl{int fchownat(int dirfd, const char *pathname, uid\_t owner, gid\_t
     group, int flags)}
+\fdesc{Modifica il proprietario di un file.} 
+}
 
-  Modifica la proprietà di un file.
-  
-  \bodydesc{la funzione restituisce gli stessi valori e gli stessi codici di
-    errore di \func{chown}, ed in più:
+{La funzione ritorna gli stessi valori e gli stessi codici di errore di
+  \func{chown}, ed in più:
   \begin{errlist}
   \item[\errcode{EBADF}] \param{dirfd} non è un file descriptor valido.
   \item[\errcode{EINVAL}] \param{flags} non ha un valore valido.
-  \item[\errcode{ENOTDIR}] \param{pathname} è un \itindsub{pathname}{relativo}
-    \textit{pathname} relativo, ma \param{dirfd} fa riferimento ad un file. 
-  \end{errlist}}
-\end{functions}
+  \item[\errcode{ENOTDIR}] \param{pathname} è un \textit{pathname} relativo,
+    ma \param{dirfd} fa riferimento ad un file.
+  \end{errlist}
+}  
+\end{funcproto}
 
 In questo caso il valore di \param{flags} stabilisce il comportamento della
 funzione quando la si applica ad un collegamento simbolico, e l'unico valore
-utilizzabile è \const{AT\_SYMLINK\_NOFOLLOW}\footnote{in \headfile{fcntl.h} è
-  definito anche \const{AT\_SYMLINK\_FOLLOW}, che richiede di dereferenziare i
-  collegamenti simbolici, essendo questo però il comportamento adottato per un
-  valore nullo di \param{flags} questo valore non viene mai usato.} che se
-impostato indica alla funzione di non eseguire la dereferenziazione di un
-eventuale collegamento simbolico, facendo comportare \func{fchownat} come
-\func{lchown} invece che come \func{chown}.
+utilizzabile è \const{AT\_SYMLINK\_NOFOLLOW}, che se impostato indica alla
+funzione di non eseguire la dereferenziazione di un eventuale collegamento
+simbolico, facendo comportare \func{fchownat} come \func{lchown} invece che
+come \func{chown}.
 
 Come accennato fra tutte quelle marcate in tab.~\ref{tab:file_atfunc_corr}
-solo due funzioni possono usare l'argomento \param{flags} con valori diversi
-da \const{AT\_SYMLINK\_NOFOLLOW}, la prima di queste è \funcd{faccessat}, ed
-il suo prototipo è:
-\begin{functions}
-  \headdecl{unistd.h}
-  \funcdecl{int faccessat(int dirfd, const char *path, int mode, int flags)}
-
-  Controlla i permessi di accesso.
-  
-  \bodydesc{la funzione restituisce gli stessi valori e gli stessi codici di
-    errore di \func{access}, ed in più:
+solo due funzioni possono usare l'argomento \param{flags} per indicare altro
+rispetto alla possibilità di seguire o meno un collegamento simbolico, la
+prima di queste è \funcd{faccessat}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int faccessat(int dirfd, const char *path, int mode, int flags)}
+\fdesc{Controlla i permessi di accesso.} 
+}
+
+{La funzione ritorna gli stessi valori e gli stessi codici di errore di
+  \func{access}, ed in più:
   \begin{errlist}
   \item[\errcode{EBADF}] \param{dirfd} non è un file descriptor valido.
   \item[\errcode{EINVAL}] \param{flags} non ha un valore valido.
-  \item[\errcode{ENOTDIR}] \param{pathname} è un \itindsub{pathname}{relativo}
-    \textit{pathname} relativo, ma \param{dirfd} fa riferimento ad un file. 
-  \end{errlist}}
-\end{functions}
-
-La funzione esegue lo stesso controllo di accesso effettuabile con
-\func{access}, ma si può utilizzare l'argomento \param{flags} per modificarne
-il comportamento rispetto a quello ordinario di \func{access}. In questo caso
-esso può essere specificato come maschera binaria di due valori:
-\begin{basedescript}{\desclabelwidth{3.0cm}}
-\item[\const{AT\_EACCES}] se impostato \funcd{faccessat} esegue il controllo
-  dei permessi usando l'\ids{UID} effettivo invece di quello reale (il
-  comportamento di default, che riprende quello di \func{access}).
-\item[\const{AT\_SYMLINK\_NOFOLLOW}] se impostato \funcd{faccessat} non esegue
-  la dereferenziazione dei collegamenti simbolici, effettuando il controllo
-  dei permessi direttamente sugli stessi.
-\end{basedescript}
+  \item[\errcode{ENOTDIR}] \param{pathname} è un \textit{pathname} relativo,
+    ma \param{dirfd} fa riferimento ad un file.
+  \end{errlist}
+}  
+\end{funcproto}
 
-La seconda eccezione è \func{unlinkat}, in questo caso l'ulteriore
-argomento \param{flags} viene utilizzato perché tramite esso la funzione possa
-comportarsi sia come analogo di \func{unlink} che di \func{rmdir}; il suo
-prototipo è:
-\begin{functions}
-  \headdecl{fcntl.h}
-  \funcdecl{int unlinkat(int dirfd, const char *pathname, int flags)}
-
-  Rimuove una voce da una directory.
-  
-  \bodydesc{la funzione restituisce gli stessi valori e gli stessi codici di
-    errore di \func{unlink} o di \func{rmdir} a seconda del valore di
-    \param{flags}, ed in più:
+La funzione esegue il controllo di accesso ad un file, ma
+l'argomento \param{flags} consente di modificarne il comportamento rispetto a
+quello ordinario di \func{access}. In questo caso esso può essere specificato
+come maschera binaria di due valori: il solito \const{AT\_SYMLINK\_NOFOLLOW},
+con il significato già spiegato, e \const{AT\_EACCES} per indicare alla
+funzione di eseguire il controllo dei permessi usando l'\ids{UID} effettivo
+invece di quello reale (il comportamento di default, che riprende quello di
+\func{access}).
+
+
+La seconda eccezione è \funcd{unlinkat}, in questo caso
+l'argomento \param{flags} viene utilizzato perché tramite esso si può indicare
+alla funzione di comportarsi sia come analogo di \func{unlink} che di
+\func{rmdir}; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{fcntl.h}
+\fdecl{int unlinkat(int dirfd, const char *pathname, int flags)}
+\fdesc{Rimuove una voce da una directory.} 
+}
+
+{La funzione ritorna gli stessi valori e gli stessi codici di errore di
+  \func{unlink} o di \func{rmdir} a seconda del valore di \param{flags}, ed in
+  più:
   \begin{errlist}
   \item[\errcode{EBADF}] \param{dirfd} non è un file descriptor valido.
   \item[\errcode{EINVAL}] \param{flags} non ha un valore valido.
-  \item[\errcode{ENOTDIR}] \param{pathname} è un \itindsub{pathname}{relativo}
-    \textit{pathname} relativo, ma \param{dirfd} fa riferimento ad un file.
-  \end{errlist}}
-\end{functions}
+  \item[\errcode{ENOTDIR}] \param{pathname} è un \textit{pathname} relativo,
+    ma \param{dirfd} fa riferimento ad un file.
+  \end{errlist}
+}  
+\end{funcproto}
 
 Di default il comportamento di \func{unlinkat} è equivalente a quello che
 avrebbe \func{unlink} applicata a \param{pathname}, fallendo in tutti i casi
 in cui questo è una directory, se però si imposta \param{flags} al valore di
-\const{AT\_REMOVEDIR},\footnote{anche se \param{flags} è una maschera binaria,
-  essendo questo l'unico flag disponibile per questa funzione, lo si può
-  assegnare direttamente.}  essa si comporterà come \func{rmdir}, in tal
+\const{AT\_REMOVEDIR}, essa si comporterà come \func{rmdir}, in tal
 caso \param{pathname} deve essere una directory, che sarà rimossa qualora
-risulti vuota.
+risulti vuota.  Non essendo in questo caso prevista la possibilità di usare
+altri valori (la funzione non segue comunque i collegamenti simbolici) anche
+se \param{flags} è una maschera binaria, essendo \const{AT\_REMOVEDIR} l'unico
+flag disponibile per questa funzione, lo si può assegnare direttamente.
+
+Infine una terza funzione, \funcm{linkat}, utilizza in maniera diversa dalle
+altre l'argomento \param{flags}, anche se in questo caso l'utilizzo continua
+ad essere attinente al comportamento con i collegamenti simbolici. Si ricordi
+che su Linux il comportamento di \func{link} è quello di non seguire mai i
+collegamenti simbolici, pertanto l'uso ordinario dell'argomento parrebbe in
+questo caso essere inutile.  A partire dal kernel 2.6.18 invece però è stato
+aggiunta per questa funzione la possibilità di usare il valore
+\const{AT\_SYMLINK\_FOLLOW}, che richiede di dereferenziare i collegamenti
+simbolici.
+
+Dato che questo è il comportamento adottato per un valore nullo
+di \param{flags} da tutte le altre funzioni, \func{linkat} è l'unica per cui
+può essere usato esplicitamente questo valore e per la quale non ha senso
+usare \const{AT\_SYMLINK\_NOFOLLOW}. Per avere un quadro d'insieme si è
+riassunto in tab.~\ref{tab:at-functions_constant_values} l'elenco delle
+costanti utilizzabili per i valori di \param{flags}.
 
-\itindend{at-functions}
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \constd{AT\_SYMLINK\_NOFOLLOW}& Se impostato la funzione non esegue la
+                                    dereferenziazione dei collegamenti
+                                    simbolici.\\ 
+    \constd{AT\_SYMLINK\_FOLLOW}& Se impostato la funzione esegue la
+                                  dereferenziazione dei collegamenti simbolici
+                                  (usato esplicitamente solo da
+                                  \func{linkat}).\\ 
+    \constd{AT\_EACCES}         & Usato solo da \func{faccessat}, richiede che
+                                  il controllo dei permessi sia fatto usando
+                                  l'\ids{UID} effettivo invece di quello
+                                  reale.\\
+    \constd{AT\_REMOVEDIR}      & Usato solo da \func{unlinkat}, richiede che
+                                  la funzione si comporti come \func{rmdir}
+                                  invece che come \func{unlink}.\\
+    \hline
+  \end{tabular}  
+  \caption{Le costanti utilizzate per i bit dell'argomento
+    aggiuntivo \param{flags} delle \textit{at-functions}.} 
+  \label{tab:at-functions_constant_values}
+\end{table}
 
 
-% TODO manca prototipo e motivazione di fexecve, da trattare qui in quanto
-% inserita nello stesso standard e da usare con openat, vedi 
-% http://pubs.opengroup.org/onlinepubs/9699939699/toc.pdf
+\texttt{ATTENZIONE PARTE DA RIVEDERE}
+
+
+Un'ultima differenza fra le \textit{at-functions} e le funzioni tradizionali
+di cui sono estensione è, come accennato in sez.~\ref{sec:file_temp_file},
+quella relativa a \func{utimensat} che non è propriamente una corrispondente
+esatta di \func{utimes} e \func{lutimes}, dato che questa funzione ha una
+maggiore precisione nella indicazione dei tempi dei file, per i quali come per
+\func{futimes}, si devono usare strutture \struct{timespec} che consentono una
+precisione fino al nanosecondo; la funzione è stata introdotta con il kernel
+2.6.22,\footnote{in precedenza, a partire dal kernel 2.6.16, era stata
+  introdotta una \textit{system call} \funcm{futimesat} seguendo una bozza
+  della revisione dello standard poi modificata; questa funzione, sostituita
+  da \func{utimensat}, è stata dichiarata obsoleta, non è supportata da
+  nessuno standard e non deve essere più utilizzata: pertanto non ne
+  parleremo.} ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/time.h}
+\fdecl{int utimensat(int dirfd, const char *pathname, const struct
+    timespec times[2], int flags)}
+\fdesc{Cambia i tempi 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}] 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{dirfd} non è \const{AT\_FDCWD} o un file
+    descriptor valido.
+  \item[\errcode{EFAULT}] \param{times} non è un puntatore valido oppure
+    \param{dirfd} è \const{AT\_FDCWD} ma \param{pathname} è \var{NULL} o non è
+    un puntatore valido.
+  \item[\errcode{EINVAL}] si sono usati dei valori non corretti per i tempi di
+    \param{times}, oppure è si usato un valore non valido per \param{flags},
+    oppure \param{pathname} è \var{NULL}, \param{dirfd} non è
+    \const{AT\_FDCWD} e \param{flags} contiene \const{AT\_SYMLINK\_NOFOLLOW}.
+  \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}).
+  \item[\errcode{ESRCH}] non c'è il permesso di attraversamento per una delle
+    componenti di \param{pathname}.
+  \end{errlist}
+  ed inoltre per entrambe \errval{EROFS} e per \func{utimensat}
+  \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR} nel
+  loro significato generico.}
+\end{funcproto}
 
+La funzione imposta i tempi dei file utilizzando i valori passati nel vettore
+di strutture \struct{timespec} esattamente come \func{futimes} (si veda quanto
+illustrato in sez.~\ref{sec:file_file_times}). 
+
+La funzione supporta invece, rispetto ad \func{utimes} che abbiamo visto in
+sez.~\ref{sec:file_file_times}, una sintassi più complessa che consente una
+indicazione sicura del file su cui operare specificando la directory su cui si
+trova tramite il file descriptor \param{dirfd} ed il suo nome come
+\textit{pathname relativo} in \param{pathname}.\footnote{su Linux solo
+  \func{utimensat} è una \textit{system call} e \func{futimens} è una funzione
+  di libreria, infatti se \param{pathname} è \var{NULL} \param{dirfd} viene
+  considerato un file descriptor ordinario e il cambiamento del tempo
+  applicato al file sottostante, qualunque esso sia, per cui
+  \code{futimens(fd, times}) è del tutto equivalente a \code{utimensat(fd,
+    NULL, times, 0)} ma nella \acr{glibc} questo comportamento è disabilitato
+  seguendo lo standard POSIX, e la funzione ritorna un errore di
+  \errval{EINVAL} se invocata in questo modo.}
+
+Torneremo su questa sintassi e sulla sua motivazione in
+sez.~\ref{sec:file_openat}, quando tratteremo tutte le altre funzioni (le
+cosiddette \textit{at-functions}) che la utilizzano; essa prevede comunque
+anche la presenza dell'argomento \param{flags} con cui attivare flag di
+controllo che modificano il comportamento della funzione, nel caso specifico
+l'unico valore consentito è \const{AT\_SYMLINK\_NOFOLLOW} che indica alla
+funzione di non dereferenziare i collegamenti simbolici, cosa che le permette
+di riprodurre le funzionalità di \func{lutimes}.
+
+
+\texttt{ATTENZIONE PARTE DA RIVEDERE}
 
 
+\itindend{at-functions}
+
+% TODO: manca prototipo e motivazione di fexecve, da trattare qui in quanto
+% inserita nello stesso standard e da usare con openat, vedi 
+% http://pubs.opengroup.org/onlinepubs/9699939699/toc.pdf
 
-\subsection{La funzione \func{fcntl}}
-\label{sec:file_fcntl}
+% TODO: manca prototipo e motivazione di execveat, vedi
+% http://man7.org/linux/man-pages/man2/execveat.2.html 
+
+\subsection{Le operazioni di controllo}
+\label{sec:file_fcntl_ioctl}
 
 Oltre alle operazioni base esaminate in sez.~\ref{sec:file_unix_interface}
 esistono tutta una serie di operazioni ausiliarie che è possibile eseguire su
 un file descriptor, che non riguardano la normale lettura e scrittura di dati,
 ma la gestione sia delle loro proprietà, che di tutta una serie di ulteriori
-funzionalità che il kernel può mettere a disposizione.\footnote{ad esempio si
-  gestiscono con questa funzione varie modalità di I/O asincrono (vedi
-  sez.~\ref{sec:file_asyncronous_operation}) e il \itindex{file~locking}
-  \textit{file locking} (vedi sez.~\ref{sec:file_locking}).}
+funzionalità che il kernel può mettere a disposizione.
 
-Per queste operazioni di manipolazione e di controllo delle varie proprietà e
-caratteristiche di un file descriptor, viene usata la funzione \funcd{fcntl},
-il cui prototipo è:
-\begin{functions}
-  \headdecl{unistd.h}
-  \headdecl{fcntl.h}
-  \funcdecl{int fcntl(int fd, int cmd)}
-  \funcdecl{int fcntl(int fd, int cmd, long arg)}
-  \funcdecl{int fcntl(int fd, int cmd, struct flock * lock)}
-  Esegue una delle possibili operazioni specificate da \param{cmd}
-  sul file \param{fd}.
-  
-  \bodydesc{La funzione ha valori di ritorno diversi a seconda
-    dell'operazione. In caso di errore il valore di ritorno è sempre $-1$ ed
-    il codice dell'errore è restituito nella variabile \var{errno}; i codici
-    possibili dipendono dal tipo di operazione, l'unico valido in generale è:
+Per le operazioni di manipolazione e di controllo delle varie proprietà e
+caratteristiche di un file descriptor, viene usata la funzione di sistema
+\funcd{fcntl},\footnote{ad esempio si gestiscono con questa funzione varie
+  modalità di I/O asincrono (vedi sez.~\ref{sec:file_asyncronous_operation}) e
+  il \textit{file locking} (vedi sez.~\ref{sec:file_locking}).} il cui
+prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{fcntl.h}
+\fdecl{int fcntl(int fd, int cmd)}
+\fdecl{int fcntl(int fd, int cmd, long arg)}
+\fdecl{int fcntl(int fd, int cmd, struct flock * lock)}
+\fdecl{int fcntl(int fd, int cmd, struct f\_owner\_ex * owner)}
+\fdesc{Esegue una operazione di controllo sul file.} 
+}
+
+{La funzione ha valori di ritorno diversi a seconda dell'operazione richiesta
+  in caso di successo mentre ritorna sempre $-1$ per un errore, nel qual caso
+  \var{errno} assumerà valori diversi che dipendono dal tipo di operazione,
+  l'unico valido in generale è:
   \begin{errlist}
   \item[\errcode{EBADF}] \param{fd} non è un file aperto.
-  \end{errlist}}
-\end{functions}
-
+  \end{errlist}
+}  
+\end{funcproto}
 
 Il primo argomento della funzione è sempre il numero di file descriptor
 \var{fd} su cui si vuole operare. Il comportamento di questa funzione, il
 numero e il tipo degli argomenti, il valore di ritorno e gli eventuali errori
-sono determinati dal valore dell'argomento \param{cmd} che in sostanza
-corrisponde all'esecuzione di un determinato \textsl{comando}; in
-sez.~\ref{sec:file_dup} abbiamo incontrato un esempio dell'uso di \func{fcntl}
-per la duplicazione dei file descriptor, una lista di tutti i possibili valori
-per \var{cmd} è riportata di seguito:
-\begin{basedescript}{\desclabelwidth{2.0cm}}
-\item[\const{F\_DUPFD}] trova il primo file descriptor disponibile di valore
-  maggiore o uguale ad \param{arg} e ne fa una copia di \param{fd}. Ritorna il
-  nuovo file descriptor in caso di successo e $-1$ in caso di errore. Gli
-  errori possibili sono \errcode{EINVAL} se \param{arg} è negativo o maggiore
-  del massimo consentito o \errcode{EMFILE} se il processo ha già raggiunto il
-  massimo numero di descrittori consentito.
-\item[\const{F\_SETFD}] imposta il valore del \textit{file descriptor flag} al
-  valore specificato con \param{arg}. Al momento l'unico bit usato è quello di
-  \itindex{close-on-exec} \textit{close-on-exec}, identificato dalla costante
-  \const{FD\_CLOEXEC}, che serve a richiedere che il file venga chiuso nella
-  esecuzione di una \func{exec} (vedi sez.~\ref{sec:proc_exec}).  Ritorna un
-  valore nullo in caso di successo e $-1$ in caso di errore.
-\item[\const{F\_GETFD}] ritorna il valore del \textit{file descriptor flag} di
-  \param{fd} o $-1$ in caso di errore; se \const{FD\_CLOEXEC} è impostato i
-  file descriptor aperti vengono chiusi attraverso una \func{exec} altrimenti
-  (il comportamento predefinito) restano aperti.
-\item[\const{F\_GETFL}] ritorna il valore del \textit{file status flag} in
-  caso di successo o $-1$ in caso di errore; permette cioè di rileggere quei
-  bit impostati da \func{open} all'apertura del file che vengono memorizzati
-  (quelli riportati nella prima e terza sezione di
-  tab.~\ref{tab:file_open_flags}).
-% TODO toglire riferimeto a tabella flag e mettere altro
-
-\item[\const{F\_SETFL}] imposta il \textit{file status flag} al valore
-  specificato da \param{arg}, ritorna un valore nullo in caso di successo o
-  $-1$ in caso di errore. Possono essere impostati solo i bit riportati nella
-  terza sezione di tab.~\ref{tab:file_open_flags}.\footnote{la pagina di
-    manuale riporta come impostabili solo \const{O\_APPEND},
-    \const{O\_NONBLOCK} e \const{O\_ASYNC}.}
-% TODO toglire riferimeto a tabella flag e mettere altro
-
-\item[\const{F\_GETLK}] richiede un controllo sul file lock specificato da
-  \param{lock}, sovrascrivendo la struttura da esso puntata con il risultato;
-  ritorna un valore nullo in caso di successo o $-1$ in caso di errore.  Questa
+aggiuntivi, sono determinati dal valore dell'argomento \param{cmd} che in
+sostanza corrisponde all'esecuzione di un determinato \textsl{comando}. A
+seconda del comando specificato il terzo argomento può essere assente (ma se
+specificato verrà ignorato), può assumere un valore intero di tipo
+\ctyp{long}, o essere un puntatore ad una struttura \struct{flock}.
+
+In sez.~\ref{sec:file_dup} abbiamo incontrato un esempio dell'uso di
+\func{fcntl} per la duplicazione dei file descriptor, una lista di tutti i
+possibili valori per \var{cmd}, e del relativo significato, dei codici di
+errore restituiti e del tipo del terzo argomento (cui faremo riferimento con
+il nome indicato nel precedente prototipo), è riportata di seguito:
+\begin{basedescript}{\desclabelwidth{1.8cm}}
+\item[\constd{F\_DUPFD}] trova il primo file descriptor disponibile di valore
+  maggiore o uguale ad \param{arg}, e ne fa un duplicato
+  di \param{fd}, ritorna il nuovo file descriptor in caso di successo e $-1$
+  in caso di errore. Oltre a \errval{EBADF} gli errori possibili sono
+  \errcode{EINVAL} se \param{arg} è negativo o maggiore del massimo consentito
+  o \errcode{EMFILE} se il processo ha già raggiunto il massimo numero di
+  descrittori consentito.
+
+\itindbeg{close-on-exec}
+
+\item[\constd{F\_DUPFD\_CLOEXEC}] ha lo stesso effetto di \const{F\_DUPFD}, ma
+  in più attiva il flag di \textit{close-on-exec} sul file descriptor
+  duplicato, in modo da evitare una successiva chiamata con
+  \const{F\_SETFD}. La funzionalità è stata introdotta con il kernel 2.6.24 ed
+  è prevista nello standard POSIX.1-2008 (si deve perciò definire
+  \macro{\_POSIX\_C\_SOURCE} ad un valore adeguato secondo quanto visto in
+  sez.~\ref{sec:intro_gcc_glibc_std}).
+
+\item[\constd{F\_GETFD}] restituisce il valore dei \textit{file descriptor
+    flags} di \param{fd} in caso di successo o $-1$ in caso di errore, il
+  terzo argomento viene ignorato. Non sono previsti errori diversi da
+  \errval{EBADF}. Al momento l'unico flag usato è quello di
+  \textit{close-on-exec}, identificato dalla costante \const{FD\_CLOEXEC}, che
+  serve a richiedere che il file venga chiuso nella esecuzione di una
+  \func{exec} (vedi sez.~\ref{sec:proc_exec}). Un valore nullo significa
+  pertanto che il flag non è impostato.
+
+\item[\constd{F\_SETFD}] imposta il valore dei \textit{file descriptor flags}
+  al valore specificato con \param{arg}, ritorna un valore nullo in caso di
+  successo e $-1$ in caso di errore. Non sono previsti errori diversi da
+  \errval{EBADF}. Dato che l'unico flag attualmente usato è quello di
+  \textit{close-on-exec}, identificato dalla costante \const{FD\_CLOEXEC},
+  tutti gli altri bit di \param{arg}, anche se impostati, vengono
+  ignorati.\footnote{questo almeno è quanto avviene fino al kernel 3.2, come
+    si può evincere dal codice della funzione \texttt{do\_fcntl} nel file
+    \texttt{fs/fcntl.c} dei sorgenti del kernel.}
+\itindend{close-on-exec}
+
+\item[\constd{F\_GETFL}] ritorna il valore dei \textit{file status flags} di
+  \param{fd} in caso di successo o $-1$ in caso di errore, il terzo argomento
+  viene ignorato. Non sono previsti errori diversi da \errval{EBADF}. Il
+  comando permette di rileggere il valore di quei bit
+  dell'argomento \param{flags} di \func{open} che vengono memorizzati nella
+  relativa voce della \textit{file table} all'apertura del file, vale a dire
+  quelli riportati in tab.~\ref{tab:open_access_mode_flag} e
+  tab.~\ref{tab:open_operation_flag}). Si ricordi che quando si usa la
+  funzione per determinare le modalità di accesso con cui è stato aperto il
+  file è necessario estrarre i bit corrispondenti nel \textit{file status
+    flag} con la maschera \const{O\_ACCMODE} come già accennato in
+  sez.~\ref{sec:file_open_close}. 
+
+\item[\constd{F\_SETFL}] imposta il valore dei \textit{file status flags} al
+  valore specificato da \param{arg}, ritorna un valore nullo in caso di
+  successo o $-1$ in caso di errore. In generale possono essere impostati solo
+  i flag riportati in tab.~\ref{tab:open_operation_flag}, su Linux si possono
+  modificare soltanto \const{O\_APPEND}, \const{O\_ASYNC}, \const{O\_DIRECT},
+  \const{O\_NOATIME} e \const{O\_NONBLOCK}. Oltre a \errval{EBADF} si otterrà
+  \errcode{EPERM} se si cerca di rimuovere \const{O\_APPEND} da un file
+  marcato come \textit{append-only} o se di cerca di impostare
+  \const{O\_NOATIME} su un file di cui non si è proprietari (e non si hanno i
+  permessi di amministratore) ed \errcode{EINVAL} se si cerca di impostare
+  \const{O\_DIRECT} su un file che non supporta questo tipo di operazioni.
+
+\item[\constd{F\_GETLK}] richiede un controllo sul file lock specificato da
+  \param{lock}, sovrascrivendo la struttura da esso puntata con il risultato,
+  ritorna un valore nullo in caso di successo o $-1$ in caso di errore. Come
+  per i due successivi comandi oltre a \errval{EBADF} se \param{lock} non è un
+  puntatore valido restituisce l'errore generico \errcode{EFAULT}. Questa
+  funzionalità è trattata in dettaglio in sez.~\ref{sec:file_posix_lock}.
+
+\item[\constd{F\_SETLK}] richiede o rilascia un file lock a seconda di quanto
+  specificato nella struttura puntata da \param{lock}, ritorna un valore nullo
+  in caso di successo e $-1$ se il file lock è tenuto da qualcun altro, nel
+  qual caso si ha un errore di \errcode{EACCES} o \errcode{EAGAIN}.  Questa
   funzionalità è trattata in dettaglio in sez.~\ref{sec:file_posix_lock}.
-\item[\const{F\_SETLK}] richiede o rilascia un file lock a seconda di quanto
-  specificato nella struttura puntata da \param{lock}. Se il lock è tenuto da
-  qualcun altro ritorna immediatamente restituendo $-1$ e imposta \var{errno} a
-  \errcode{EACCES} o \errcode{EAGAIN}, in caso di successo ritorna un valore
-  nullo. Questa funzionalità è trattata in dettaglio in
-  sez.~\ref{sec:file_posix_lock}.
-\item[\const{F\_SETLKW}] identica a \const{F\_SETLK} eccetto per il fatto che
-  la funzione non ritorna subito ma attende che il blocco sia rilasciato. Se
+
+\item[\constd{F\_SETLKW}] identica a \const{F\_SETLK} eccetto per il fatto che
+  la funzione non ritorna subito ma attende che il blocco sia rilasciato, se
   l'attesa viene interrotta da un segnale la funzione restituisce $-1$ e
-  imposta \var{errno} a \errcode{EINTR}, in caso di successo ritorna un valore
-  nullo.  Questa funzionalità è trattata in dettaglio in
-  sez.~\ref{sec:file_posix_lock}.
-\item[\const{F\_GETOWN}] restituisce il \ids{PID} del processo o
-  l'identificatore del \itindex{process~group} \textit{process
-    group}\footnote{i \itindex{process~group} \textit{process group} sono
-    (vedi sez.~\ref{sec:sess_proc_group}) raggruppamenti di processi usati nel
-    controllo di sessione; a ciascuno di essi è associato un identificatore
-    (un numero positivo analogo al \ids{PID}).} che è preposto alla ricezione
-  dei segnali \signal{SIGIO}\footnote{o qualunque altro segnale alternativo
-    impostato con \const{F\_FSETSIG}.} per gli eventi associati al file
-  descriptor \param{fd}\footnote{il segnale viene usato sia per il
-    \textit{Signal Drive I/O}, che tratteremo in
-    sez.~\ref{sec:file_asyncronous_operation}, e dai vari meccanismi di
-    notifica asincrona, che tratteremo in
-    sez.~\ref{sec:file_asyncronous_lease}.} e \signal{SIGURG} per la notifica
-  dei dati urgenti di un socket.\footnote{vedi
-    sez.~\ref{sec:TCP_urgent_data}.} Nel caso di un \textit{process group}
-  viene restituito un valore negativo il cui valore assoluto corrisponde
-  all'identificatore del \itindex{process~group} \textit{process group}.  In
-  caso di errore viene restituito $-1$.
-\item[\const{F\_SETOWN}] imposta, con il valore dell'argomento \param{arg},
-  l'identificatore del processo o del \itindex{process~group} \textit{process
-    group} che riceverà i segnali \signal{SIGIO}  e \signal{SIGURG} per gli
-  eventi associati al file descriptor \param{fd}, ritorna un valore nullo in
-  caso di successo o $-1$ in caso di errore.  Come per \const{F\_GETOWN}, per
-  impostare un \itindex{process~group} \textit{process group} si deve usare
-  per \param{arg} un valore negativo, il cui valore assoluto corrisponde
-  all'identificatore del \itindex{process~group} \textit{process group}.
-\item[\const{F\_GETSIG}] restituisce il valore del segnale inviato quando ci
-  sono dati disponibili in ingresso su un file descriptor aperto ed impostato
-  per l'I/O asincrono (si veda sez.~\ref{sec:file_asyncronous_io}). Il valore 0
-  indica il valore predefinito (che è \signal{SIGIO}), un valore diverso da
-  zero indica il segnale richiesto, (che può essere anche lo stesso
-  \signal{SIGIO}). In caso di errore ritorna $-1$.
-\item[\const{F\_SETSIG}] imposta il segnale da inviare quando diventa
-  possibile effettuare I/O sul file descriptor in caso di I/O asincrono,
-  ritorna un valore nullo in caso di successo o $-1$ in caso di errore. Il
-  valore zero indica di usare il segnale predefinito, \signal{SIGIO}. Un altro
-  valore diverso da zero (compreso lo stesso \signal{SIGIO}) specifica il
-  segnale voluto; l'uso di un valore diverso da zero permette inoltre, se si è
+  imposta \var{errno} a \errcode{EINTR}.  Questa funzionalità è trattata in
+  dettaglio in sez.~\ref{sec:file_posix_lock}.
+
+\item[\constd{F\_GETOWN}] restituisce in caso di successo l'identificatore del
+  processo o del \textit{process group} (vedi sez.~\ref{sec:sess_proc_group})
+  che è preposto alla ricezione del segnale \signal{SIGIO} (o l'eventuale
+  segnale alternativo impostato con \const{F\_SETSIG}) per gli eventi
+  asincroni associati al file descriptor \param{fd} e del segnale
+  \signal{SIGURG} per la notifica dei dati urgenti di un socket (vedi
+  sez.~\ref{sec:TCP_urgent_data}). Restituisce $-1$ in caso di errore ed il
+  terzo argomento viene ignorato. Non sono previsti errori diversi da
+  \errval{EBADF}.
+
+  Per distinguerlo dal caso in cui il segnale viene inviato a un singolo
+  processo, nel caso di un \textit{process group} viene restituito un valore
+  negativo il cui valore assoluto corrisponde all'identificatore del
+  \textit{process group}. Con Linux questo comporta un problema perché se il
+  valore restituito dalla \textit{system call} è compreso nell'intervallo fra
+  $-1$ e $-4095$ in alcune architetture questo viene trattato dalla
+  \acr{glibc} come un errore,\footnote{il problema deriva dalle limitazioni
+    presenti in architetture come quella dei normali PC (i386) per via delle
+    modalità in cui viene effettuata l'invocazione delle \textit{system call}
+    che non consentono di restituire un adeguato codice di ritorno.} per cui
+  in tal caso \func{fcntl} ritornerà comunque $-1$ mentre il valore restituito
+  dalla \textit{system call} verrà assegnato ad \var{errno}, cambiato di
+  segno.
+
+  Per questo motivo con il kernel 2.6.32 è stato introdotto il comando
+  alternativo \const{F\_GETOWN\_EX}, che vedremo a breve, che consente di
+  evitare il problema. A partire dalla versione 2.11 la \acr{glibc}, se
+  disponibile, usa questa versione alternativa per mascherare il problema
+  precedente e restituire un valore corretto in tutti i casi.\footnote{in cui
+    cioè viene restituito un valore negativo corretto qualunque sia
+    l'identificatore del \textit{process group}, che non potendo avere valore
+    unitario (non esiste infatti un \textit{process group} per \cmd{init}) non
+    può generare ambiguità con il codice di errore.} Questo però comporta che
+  il comportamento del comando può risultare diverso a seconda delle versioni
+  della \acr{glibc} e del kernel.
+
+\item[\constd{F\_SETOWN}] imposta, con il valore dell'argomento \param{arg},
+  l'identificatore del processo o del \textit{process group} che riceverà i
+  segnali \signal{SIGIO} e \signal{SIGURG} per gli eventi associati al file
+  descriptor \param{fd}. Ritorna un valore nullo in caso di successo o $-1$ in
+  caso di errore. Oltre a \errval{EBADF} gli errori possibili sono
+  \errcode{ESRCH} se \param{arg} indica un processo o un \textit{process
+    group} inesistente.
+
+  L'impostazione è soggetta alle stesse restrizioni presenti sulla funzione
+  \func{kill} (vedi sez.~\ref{sec:sig_kill_raise}), per cui un utente non
+  privilegiato può inviare i segnali solo ad un processo che gli appartiene,
+  in genere comunque si usa il processo corrente.  Come per \const{F\_GETOWN},
+  per indicare un \textit{process group} si deve usare per \param{arg} un
+  valore negativo, il cui valore assoluto corrisponda all'identificatore del
+  \textit{process group}.
+
+  A partire dal kernel 2.6.12 se si sta operando con i \textit{thread} della
+  implementazione nativa di Linux (quella della NTPL, vedi
+  sez.~\ref{sec:linux_ntpl}) e se si è impostato un segnale specifico con
+  \const{F\_SETSIG}, un valore positivo di \param{arg} viene interpretato come
+  indicante un \textit{Thread ID} e non un \textit{Process ID}.  Questo
+  consente di inviare il segnale impostato con \const{F\_SETSIG} ad uno
+  specifico \textit{thread}. In genere questo non comporta differenze
+  significative per il processi ordinari, in cui non esistono altri
+  \textit{thread}, dato che su Linux il \textit{thread} principale, che in tal
+  caso è anche l'unico, mantiene un valore del \textit{Thread ID} uguale al
+  \ids{PID} del processo. Il problema è però che questo comportamento non si
+  applica a \signal{SIGURG}, per il quale \param{arg} viene sempre
+  interpretato come l'identificatore di un processo o di un \textit{process
+    group}.
+
+\item[\constd{F\_GETOWN\_EX}] legge nella struttura puntata
+  dall'argomento \param{owner} l'identificatore del processo, \textit{thread}
+  o \textit{process group} (vedi sez.~\ref{sec:sess_proc_group}) che è
+  preposto alla ricezione dei segnali \signal{SIGIO} e \signal{SIGURG} per gli
+  eventi associati al file descriptor \param{fd}.  Ritorna un valore nullo in
+  caso di successo o $-1$ in caso di errore. Oltre a \errval{EBADF} e da
+  \errval{EFAULT} se \param{owner} non è un puntatore valido.
+
+  Il comando, che è disponibile solo a partire dal kernel 2.6.32, effettua lo
+  stesso compito di \const{F\_GETOWN} di cui costituisce una evoluzione che
+  consente di superare i limiti e le ambiguità relative ai valori restituiti
+  come identificativo. A partire dalla versione 2.11 della \acr{glibc} esso
+  viene usato dalla libreria per realizzare una versione di \func{fcntl} che
+  non presenti i problemi illustrati in precedenza per la versione precedente
+  di \const{F\_GETOWN}.  Il comando è specifico di Linux ed utilizzabile solo
+  se si è definita la macro \macro{\_GNU\_SOURCE}.
+
+\item[\constd{F\_SETOWN\_EX}] imposta con il valore della struttura
+  \struct{f\_owner\_ex} puntata \param{owner}, l'identificatore del processo o
+  del \textit{process group} che riceverà i segnali \signal{SIGIO} e
+  \signal{SIGURG} per gli eventi associati al file
+  descriptor \param{fd}. Ritorna un valore nullo in caso di successo o $-1$ in
+  caso di errore, con gli stessi errori di \const{F\_SETOWN} più
+  \errcode{EINVAL} se il campo \var{type} di \struct{f\_owner\_ex} non indica
+  un tipo di identificatore valido.
+
+  \begin{figure}[!htb]
+    \footnotesize \centering
+    \begin{varwidth}[c]{0.5\textwidth}
+      \includestruct{listati/f_owner_ex.h}
+    \end{varwidth}
+    \normalsize 
+    \caption{La struttura \structd{f\_owner\_ex}.} 
+    \label{fig:f_owner_ex}
+  \end{figure}
+
+  Come \const{F\_GETOWN\_EX} il comando richiede come terzo argomento il
+  puntatore ad una struttura \struct{f\_owner\_ex} la cui definizione è
+  riportata in fig.~\ref{fig:f_owner_ex}, in cui il primo campo indica il tipo
+  di identificatore il cui valore è specificato nel secondo campo, che assume
+  lo stesso significato di \param{arg} per \const{F\_SETOWN}. Per il campo
+  \var{type} i soli valori validi sono \constd{F\_OWNER\_TID},
+  \constd{F\_OWNER\_PID} e \constd{F\_OWNER\_PGRP}, che indicano
+  rispettivamente che si intende specificare con \var{pid} un \textit{Tread
+    ID}, un \textit{Process ID} o un \textit{Process Group ID}. A differenza
+  di \const{F\_SETOWN} se si specifica un \textit{Tread ID} questo riceverà
+  sia \signal{SIGIO} (o il segnale impostato con \const{F\_SETSIG}) che
+  \signal{SIGURG}. Il comando è specifico di Linux, è disponibile solo a
+  partire dal kernel 2.6.32, ed è utilizzabile solo se si è definita la macro
+  \macro{\_GNU\_SOURCE}.
+
+\item[\constd{F\_GETSIG}] restituisce il valore del segnale inviato dai vari
+  meccanismi di I/O asincrono associati al file descriptor \param{fd} (quelli
+  trattati in sez.~\ref{sec:file_asyncronous_operation}) in caso di successo o
+  $-1$ in caso di errore, il terzo argomento viene ignorato. Non sono previsti
+  errori diversi da \errval{EBADF}.  Un valore nullo indica che si sta usando
+  il segnale predefinito, che è \signal{SIGIO}. Un valore diverso da zero
+  indica il segnale che è stato impostato con \const{F\_SETSIG}, che può
+  essere anche lo stesso \signal{SIGIO}. Il comando è specifico di Linux ed
+  utilizzabile solo se si è definita la macro \macro{\_GNU\_SOURCE}.
+
+\item[\constd{F\_SETSIG}] imposta il segnale inviato dai vari meccanismi di
+  I/O asincrono associati al file descriptor \param{fd} (quelli trattati in
+  sez.~\ref{sec:file_asyncronous_operation}) al valore indicato
+  da \param{arg}, ritorna un valore nullo in caso di successo o $-1$ in caso
+  di errore.  Oltre a \errval{EBADF} gli errori possibili sono
+  \errcode{EINVAL} se \param{arg} indica un numero di segnale non valido.  Un
+  valore nullo di \param{arg} indica di usare il segnale predefinito, cioè
+  \signal{SIGIO}. Un valore diverso da zero, compreso lo stesso
+  \signal{SIGIO}, specifica il segnale voluto.  Il comando è specifico di
+  Linux ed utilizzabile solo se si è definita la macro \macro{\_GNU\_SOURCE}.
+
+  L'impostazione di un valore diverso da zero permette inoltre, se si è
   installato il gestore del segnale come \var{sa\_sigaction} usando
   \const{SA\_SIGINFO}, (vedi sez.~\ref{sec:sig_sigaction}), di rendere
   disponibili al gestore informazioni ulteriori riguardo il file che ha
-  generato il segnale attraverso i valori restituiti in \struct{siginfo\_t}
-  (come vedremo in sez.~\ref{sec:file_asyncronous_io}).\footnote{i due comandi
-    \const{F\_SETSIG} e \const{F\_GETSIG} sono una estensione specifica di
-    Linux.}
-\item[\const{F\_SETLEASE}] imposta o rimuove un \itindex{file~lease}
-  \textit{file lease}\footnote{questa è una nuova funzionalità, specifica di
-    Linux, e presente solo a partire dai kernel della serie 2.4.x, in cui il
-    processo che detiene un \textit{lease} su un file riceve una notifica
-    qualora un altro processo cerca di eseguire una \func{open} o una
-    \func{truncate} su di esso.} sul file descriptor \var{fd} a seconda del
-  valore del terzo argomento, che in questo caso è un \ctyp{int}, ritorna un
-  valore nullo in caso di successo o $-1$ in caso di errore. Questa
-  funzionalità avanzata è trattata in dettaglio in
-  sez.~\ref{sec:file_asyncronous_lease}.
-\item[\const{F\_GETLEASE}] restituisce il tipo di \itindex{file~lease}
-  \textit{file lease} che il processo detiene nei confronti del file
-  descriptor \var{fd} o $-1$ in caso di errore. Con questo comando il terzo
-  argomento può essere omesso. Questa funzionalità avanzata è trattata in
+  generato il segnale attraverso i valori restituiti in
+  \struct{siginfo\_t}. Se inoltre si imposta un segnale \textit{real-time} si
+  potranno sfruttare le caratteristiche di avanzate di questi ultimi (vedi
+  sez.~\ref{sec:sig_real_time}), ed in particolare la capacità di essere
+  accumulati in una coda prima della notifica.
+
+\item[\constd{F\_GETLEASE}] restituisce il tipo di \textit{file lease} che il
+  processo detiene nei confronti del file descriptor \var{fd} o $-1$ in caso
+  di errore, il terzo argomento viene ignorato. Non sono previsti errori
+  diversi da \errval{EBADF}.  Il comando è specifico di Linux ed utilizzabile
+  solo se si è definita la macro \macro{\_GNU\_SOURCE}.  Questa funzionalità è
+  trattata in dettaglio in sez.~\ref{sec:file_asyncronous_lease}.
+
+\item[\constd{F\_SETLEASE}] imposta o rimuove a seconda del valore
+  di \param{arg} un \textit{file lease} sul file descriptor \var{fd} a seconda
+  del valore indicato da \param{arg}. Ritorna un valore nullo in caso di
+  successo o $-1$ in caso di errore. Oltre a \errval{EBADF} si otterrà
+  \errcode{EINVAL} se si è specificato un valore non valido per \param{arg}
+  (deve essere usato uno dei valori di tab.~\ref{tab:file_lease_fctnl}),
+  \errcode{ENOMEM} se non c'è memoria sufficiente per creare il \textit{file
+    lease}, \errcode{EACCES} se non si è il proprietario del file e non si
+  hanno i privilegi di amministratore.\footnote{per la precisione occorre la
+    capacità \const{CAP\_LEASE}.}
+
+  Il supporto il supporto per i \textit{file lease}, che consente ad un
+  processo che detiene un \textit{lease} su un file di riceve una notifica
+  qualora un altro processo cerchi di eseguire una \func{open} o una
+  \func{truncate} su di esso è stato introdotto a partire dai kernel della
+  serie 2.4 Il comando è specifico di Linux ed utilizzabile solo se si è
+  definita la macro \macro{\_GNU\_SOURCE}. Questa funzionalità è trattata in
   dettaglio in sez.~\ref{sec:file_asyncronous_lease}.
-\item[\const{F\_NOTIFY}] attiva un meccanismo di notifica per cui viene
-  riportata al processo chiamante, tramite il segnale \signal{SIGIO} (o altro
-  segnale specificato con \const{F\_SETSIG}) ogni modifica eseguita o
+
+\item[\constd{F\_NOTIFY}] attiva il meccanismo di notifica asincrona per cui
+  viene riportato al processo chiamante, tramite il segnale \signal{SIGIO} (o
+  altro segnale specificato con \const{F\_SETSIG}) ogni modifica eseguita o
   direttamente sulla directory cui \var{fd} fa riferimento, o su uno dei file
-  in essa contenuti; ritorna un valore nullo in caso di successo o $-1$ in caso
-  di errore. Questa funzionalità avanzata, disponibile dai kernel della serie
-  2.4.x, è trattata in dettaglio in sez.~\ref{sec:file_asyncronous_lease}.
+  in essa contenuti; ritorna un valore nullo in caso di successo o $-1$ in
+  caso di errore. Il comando è specifico di Linux ed utilizzabile solo se si è
+  definita la macro \macro{\_GNU\_SOURCE}.  Questa funzionalità, disponibile
+  dai kernel della serie 2.4.x, è trattata in dettaglio in
+  sez.~\ref{sec:file_asyncronous_lease}.
+
+\item[\constd{F\_GETPIPE\_SZ}] restituisce in caso di successo la dimensione
+  del buffer associato alla \textit{pipe} \param{fd} (vedi
+  sez.~\ref{sec:ipc_pipes}) o $-1$ in caso di errore, il terzo argomento viene
+  ignorato. Non sono previsti errori diversi da \errval{EBADF}, che viene
+  restituito anche se il file descriptor non è una \textit{pipe}. Il comando è
+  specifico di Linux, è disponibile solo a partire dal kernel 2.6.35, ed è
+  utilizzabile solo se si è definita la macro \macro{\_GNU\_SOURCE}.
+
+\item[\constd{F\_SETPIPE\_SZ}] imposta la dimensione del buffer associato alla
+  \textit{pipe} \param{fd} (vedi sez.~\ref{sec:ipc_unix}) ad un valore uguale
+  o superiore a quello indicato dall'argomento \param{arg}. Ritorna un valore
+  nullo in caso di successo o $-1$ in caso di errore. Oltre a \errval{EBADF}
+  gli errori possibili sono \errcode{EBUSY} se si cerca di ridurre la
+  dimensione del buffer al di sotto della quantità di dati effettivamente
+  presenti su di esso ed \errcode{EPERM} se un processo non privilegiato cerca
+  di impostare un valore troppo alto.  La dimensione minima del buffer è pari
+  ad una pagina di memoria, a cui verrà comunque arrotondata ogni dimensione
+  inferiore, il valore specificato viene in genere arrotondato per eccesso al
+  valore ritenuto più opportuno dal sistema, pertanto una volta eseguita la
+  modifica è opportuno rileggere la nuova dimensione con
+  \const{F\_GETPIPE\_SZ}. I processi non privilegiati\footnote{per la
+    precisione occorre la capacità \const{CAP\_SYS\_RESOURCE}.} non possono
+  impostare un valore superiore a quello indicato da
+  \sysctlfiled{fs/pipe-size-max}.  Il comando è specifico di Linux, è
+  disponibile solo a partire dal kernel 2.6.35, ed è utilizzabile solo se si è
+  definita la macro \macro{\_GNU\_SOURCE}.
+
 \end{basedescript}
 
-La maggior parte delle funzionalità di \func{fcntl} sono troppo avanzate per
-poter essere affrontate in tutti i loro aspetti a questo punto; saranno
-pertanto riprese più avanti quando affronteremo le problematiche ad esse
-relative. In particolare le tematiche relative all'I/O asincrono e ai vari
-meccanismi di notifica saranno trattate in maniera esaustiva in
-sez.~\ref{sec:file_asyncronous_access} mentre quelle relative al
-\itindex{file~locking} \textit{file locking} saranno esaminate in
-sez.~\ref{sec:file_locking}). L'uso di questa funzione con i socket verrà
-trattato in sez.~\ref{sec:sock_ctrl_func}.
-
-Si tenga presente infine che quando si usa la funzione per determinare le
-modalità di accesso con cui è stato aperto il file (attraverso l'uso del
-comando \const{F\_GETFL}) è necessario estrarre i bit corrispondenti nel
-\textit{file status flag} che si è ottenuto.  Infatti la definizione corrente
-di quest'ultimo non assegna bit separati alle tre diverse modalità
-\const{O\_RDONLY}, \const{O\_WRONLY} e \const{O\_RDWR}.\footnote{in Linux
-  queste costanti sono poste rispettivamente ai valori 0, 1 e 2.} Per questo
-motivo il valore della modalità di accesso corrente si ottiene eseguendo un
-AND binario del valore di ritorno di \func{fcntl} con la maschera
-\const{O\_ACCMODE} (anch'essa definita in \headfile{fcntl.h}), che estrae i
-bit di accesso dal \textit{file status flag}.
-
-
-
-\subsection{La funzione \func{ioctl}}
-\label{sec:file_ioctl}
-
-Benché il concetto di \textit{everything is a file} si sia dimostrato molto
-valido anche per l'interazione con i dispositivi più vari, fornendo una
-interfaccia che permette di interagire con essi tramite le stesse funzioni
-usate per i normali file di dati, esisteranno sempre caratteristiche
-peculiari, specifiche dell'hardware e della funzionalità che ciascun
-dispositivo può provvedere, che non possono venire comprese in questa
-interfaccia astratta (un caso tipico è l'impostazione della velocità di una
-porta seriale, o le dimensioni di un framebuffer).
+% TODO: trattare RWH_WRITE_LIFE_EXTREME e RWH_WRITE_LIFE_SHORT aggiunte con
+% il kernel 4.13 (vedi https://lwn.net/Articles/727385/)
+
+La maggior parte delle funzionalità controllate dai comandi di \func{fcntl}
+sono avanzate e richiedono degli approfondimenti ulteriori, saranno pertanto
+riprese più avanti quando affronteremo le problematiche ad esse relative. In
+particolare le tematiche relative all'I/O asincrono e ai vari meccanismi di
+notifica saranno trattate in maniera esaustiva in
+sez.~\ref{sec:file_asyncronous_operation} mentre quelle relative al
+\textit{file locking} saranno esaminate in sez.~\ref{sec:file_locking}). L'uso
+di questa funzione con i socket verrà trattato in
+sez.~\ref{sec:sock_ctrl_func}.
+
+La gran parte dei comandi di \func{fcntl} (come \const{F\_DUPFD},
+\const{F\_GETFD}, \const{F\_SETFD}, \const{F\_GETFL}, \const{F\_SETFL},
+\const{F\_GETLK}, \const{F\_SETLK} e \const{F\_SETLKW}) sono previsti da SVr4
+e 4.3BSD e standardizzati in POSIX.1-2001 che inoltre prevede gli ulteriori
+\const{F\_GETOWN} e \const{F\_SETOWN}. Pertanto nell'elenco si sono indicate
+esplicitamente soltanto le ulteriori richieste in termini delle macro di
+funzionalità di sez.~\ref{sec:intro_gcc_glibc_std} soltanto per le
+funzionalità inserite in standard successivi o specifiche di Linux.
+
+
+% \subsection{La funzione \func{ioctl}}
+% \label{sec:file_ioctl}
+
+Benché l'interfaccia di gestione dell'I/O sui file di cui abbiamo parlato
+finora si sia dimostrata valida anche per l'interazione diretta con le
+periferiche attraverso i loro file di dispositivo, consentendo di usare le
+stesse funzioni utilizzate per i normali file di dati, esistono però
+caratteristiche peculiari, specifiche dell'hardware e delle funzionalità che
+ciascun dispositivo può provvedere, che non possono venire comprese in questa
+interfaccia astratta come ad esempio l'impostazione della velocità di una
+porta seriale, o le dimensioni di un framebuffer.
 
 Per questo motivo nell'architettura del sistema è stata prevista l'esistenza
-di una funzione apposita, \funcd{ioctl}, con cui poter compiere le operazioni
-specifiche di ogni dispositivo particolare, usando come riferimento il solito
-file descriptor.  Il prototipo di questa funzione è:
-\begin{prototype}{sys/ioctl.h}{int ioctl(int fd, int request, ...)}  
-
-  Esegue l'operazione di controllo specificata da \param{request} sul file
-  descriptor \param{fd}.
-  
-  \bodydesc{La funzione nella maggior parte dei casi ritorna 0, alcune
-    operazioni usano però il valore di ritorno per restituire informazioni. In
-    caso di errore viene sempre restituito $-1$ ed \var{errno} assumerà uno dei
-    valori:
+di una apposita funzione di sistema, \funcd{ioctl}, come meccanismo generico
+per compiere operazioni specializzate; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/ioctl.h}
+\fdecl{int ioctl(int fd, int request, ...)}
+\fdesc{Esegue una operazione speciale.} 
+}
+
+{La funzione ritorna $0$ in caso di successo nella maggior parte dei casi, ma
+  alcune operazioni possono restituire un valore positivo, mentre ritorna
+  sempre $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei
+  valori:
   \begin{errlist}
+  \item[\errcode{EINVAL}] gli argomenti \param{request} o \param{argp} non sono
+    validi.
   \item[\errcode{ENOTTY}] il file \param{fd} non è associato con un
     dispositivo, o la richiesta non è applicabile all'oggetto a cui fa
     riferimento \param{fd}.
-  \item[\errcode{EINVAL}] gli argomenti \param{request} o \param{argp} non sono
-    validi.
   \end{errlist}
-  ed inoltre \errval{EBADF} e \errval{EFAULT}.}
-\end{prototype}
-
-La funzione serve in sostanza come meccanismo generico per fare tutte quelle
-operazioni che non rientrano nell'interfaccia ordinaria della gestione dei
-file e che non è possibile effettuare con le funzioni esaminate finora. La
-funzione richiede che si passi come primo argomento un file descriptor
-regolarmente aperto, e l'operazione da compiere viene selezionata attraverso
-il valore dell'argomento \param{request}. Il terzo argomento dipende
-dall'operazione prescelta; tradizionalmente è specificato come \code{char *
-  argp}, da intendersi come puntatore ad un area di memoria
-generica,\footnote{all'epoca della creazione di questa funzione infatti ancora
-  non era stato introdotto il tipo \ctyp{void}.} ma per certe operazioni può
-essere omesso, e per altre è un semplice intero.
+  ed inoltre \errval{EBADF} e \errval{EFAULT} nel loro significato generico.}
+\end{funcproto}
+
+
+La funzione richiede che si passi come primo argomento un file
+descriptor \param{fd} regolarmente aperto, mentre l'operazione da compiere
+deve essere indicata dal valore dell'argomento \param{request}. Il terzo
+argomento dipende dall'operazione prescelta; tradizionalmente è specificato
+come \code{char * argp}, da intendersi come puntatore ad un area di memoria
+generica (all'epoca della creazione di questa funzione infatti ancora non era
+stato introdotto il tipo \ctyp{void}) ma per certe operazioni può essere
+omesso, e per altre è un semplice intero.
 
 Normalmente la funzione ritorna zero in caso di successo e $-1$ in caso di
-errore, ma per alcune operazione il valore di ritorno, che nel caso viene
-impostato ad un valore positivo, può essere utilizzato come parametro di
-uscita. È più comune comunque restituire i risultati all'indirizzo puntato dal
-terzo argomento.
+errore, ma per alcune operazioni il valore di ritorno, che nel caso viene
+impostato ad un valore positivo, può essere utilizzato come indicazione del
+risultato della stessa. È più comune comunque restituire i risultati
+all'indirizzo puntato dal terzo argomento.
 
 Data la genericità dell'interfaccia non è possibile classificare in maniera
 sistematica le operazioni che si possono gestire con \func{ioctl}, un breve
@@ -1875,7 +2518,7 @@ elenco di alcuni esempi di esse è il seguente:
 \begin{itemize*}
 \item il cambiamento dei font di un terminale.
 \item l'esecuzione di una traccia audio di un CDROM.
-\item i comandi di avanti veloce e riavvolgimento di un nastro.
+\item i comandi di avanti veloce e di riavvolgimento di un nastro.
 \item il comando di espulsione di un dispositivo rimovibile.
 \item l'impostazione della velocità trasmissione di una linea seriale.
 \item l'impostazione della frequenza e della durata dei suoni emessi dallo
@@ -1888,7 +2531,7 @@ elenco di alcuni esempi di esse è il seguente:
 
 In generale ogni dispositivo ha un suo insieme di operazioni specifiche
 effettuabili attraverso \func{ioctl}, tutte queste sono definite nell'header
-file \headfile{sys/ioctl.h}, e devono essere usate solo sui dispositivi cui
+file \headfiled{sys/ioctl.h}, e devono essere usate solo sui dispositivi cui
 fanno riferimento. Infatti anche se in genere i valori di \param{request} sono
 opportunamente differenziati a seconda del dispositivo\footnote{il kernel usa
   un apposito \textit{magic number} per distinguere ciascun dispositivo nella
@@ -1904,56 +2547,55 @@ imprevedibili o indesiderati.
 
 Data la assoluta specificità della funzione, il cui comportamento varia da
 dispositivo a dispositivo, non è possibile fare altro che dare una descrizione
-sommaria delle sue caratteristiche; torneremo ad esaminare in
-seguito\footnote{per l'uso di \func{ioctl} con i socket si veda
-  sez.~\ref{sec:sock_ctrl_func}.} quelle relative ad alcuni casi specifici (ad
-esempio la gestione dei terminali è effettuata attraverso \func{ioctl} in
-quasi tutte le implementazioni di Unix), qui riportiamo solo l'elenco delle
-operazioni che sono predefinite per qualunque file,\footnote{in particolare
-  queste operazioni sono definite nel kernel a livello generale, e vengono
-  sempre interpretate per prime, per cui, come illustrato in \cite{LinDevDri},
-  eventuali operazioni specifiche che usino lo stesso valore verrebbero
-  ignorate.}  caratterizzate dal prefisso \texttt{FIO}:
+sommaria delle sue caratteristiche; torneremo ad esaminare in seguito quelle
+relative ad alcuni casi specifici, ad esempio la gestione dei terminali è
+effettuata attraverso \func{ioctl} in quasi tutte le implementazioni di Unix,
+mentre per l'uso di \func{ioctl} con i socket si veda
+sez.~\ref{sec:sock_ctrl_func}. 
+
+Riportiamo qui solo l'elenco delle operazioni che sono predefinite per
+qualunque file, caratterizzate dal prefisso \texttt{FIO}. Queste operazioni
+sono definite nel kernel a livello generale, e vengono sempre interpretate per
+prime, per cui, come illustrato in \cite{LinDevDri}, eventuali operazioni
+specifiche che usino lo stesso valore verrebbero ignorate:
 \begin{basedescript}{\desclabelwidth{2.0cm}}
-\item[\const{FIOCLEX}] imposta il flag di \itindex{close-on-exec}
-  \textit{close-on-exec} sul file, in questo caso, essendo usata come
-  operazione logica, \func{ioctl} non richiede un terzo argomento, il cui
-  eventuale valore viene ignorato.
-\item[\const{FIONCLEX}] cancella il flag di \itindex{close-on-exec}
-  \textit{close-on-exec} sul file, in questo caso, essendo usata come
-  operazione logica, \func{ioctl} non richiede un terzo argomento, il cui
-  eventuale valore viene ignorato.
-\item[\const{FIOASYNC}] abilita o disabilita la modalità di I/O asincrono sul
-  file (vedi sez.~\ref{sec:file_asyncronous_operation}); il terzo argomento
+\item[\constd{FIOCLEX}] imposta il flag di \textit{close-on-exec} sul file, in
+  questo caso, essendo usata come operazione logica, \func{ioctl} non richiede
+  un terzo argomento, il cui eventuale valore viene ignorato.
+\item[\constd{FIONCLEX}] cancella il flag di \textit{close-on-exec} sul file,
+  in questo caso, essendo usata come operazione logica, \func{ioctl} non
+  richiede un terzo argomento, il cui eventuale valore viene ignorato.
+\item[\constd{FIOASYNC}] abilita o disabilita la modalità di I/O asincrono sul
+  file (vedi sez.~\ref{sec:signal_driven_io}); il terzo argomento
   deve essere un puntatore ad un intero (cioè di tipo \texttt{const int *})
   che contiene un valore logico (un valore nullo disabilita, un valore non
   nullo abilita).
-\item[\const{FIONBIO}] abilita o disabilita sul file l'I/O in modalità non
+\item[\constd{FIONBIO}] abilita o disabilita sul file l'I/O in modalità non
   bloccante; il terzo argomento deve essere un puntatore ad un intero (cioè di
   tipo \texttt{const int *}) che contiene un valore logico (un valore nullo
   disabilita, un valore non nullo abilita).
-\item[\const{FIOSETOWN}] imposta il processo che riceverà i segnali
+\item[\constd{FIOSETOWN}] imposta il processo che riceverà i segnali
   \signal{SIGURG} e \signal{SIGIO} generati sul file; il terzo argomento deve
   essere un puntatore ad un intero (cioè di tipo \texttt{const int *}) il cui
   valore specifica il PID del processo.
-\item[\const{FIOGETOWN}] legge il processo che riceverà i segnali
+\item[\constd{FIOGETOWN}] legge il processo che riceverà i segnali
   \signal{SIGURG} e \signal{SIGIO} generati sul file; il terzo argomento deve
   essere un puntatore ad un intero (cioè di tipo \texttt{int *}) su cui sarà
   scritto il PID del processo.
-\item[\const{FIONREAD}] legge il numero di byte disponibili in lettura sul
-  file descriptor;\footnote{questa operazione è disponibile solo su alcuni
-    file descriptor, in particolare sui socket (vedi
-    sez.~\ref{sec:sock_ioctl_IP}) o sui file descriptor di \textit{epoll}
-    (vedi sez.~\ref{sec:file_epoll}).} il terzo argomento deve essere un
-  puntatore ad un intero (cioè di tipo \texttt{int *}) su cui sarà restituito
-  il valore.
-\item[\const{FIOQSIZE}] restituisce la dimensione corrente di un file o di una
+\item[\constd{FIONREAD}] legge il numero di byte disponibili in lettura sul
+  file descriptor; questa operazione è disponibile solo su alcuni file
+  descriptor, in particolare sui socket (vedi sez.~\ref{sec:sock_ioctl_IP}) o
+  sui file descriptor di \textit{epoll} (vedi sez.~\ref{sec:file_epoll}), il
+  terzo argomento deve essere un puntatore ad un intero (cioè di tipo
+  \texttt{int *}) su cui sarà restituito il valore.
+\item[\constd{FIOQSIZE}] restituisce la dimensione corrente di un file o di una
   directory, mentre se applicata ad un dispositivo fallisce con un errore di
   \errcode{ENOTTY}; il terzo argomento deve essere un puntatore ad un intero
   (cioè di tipo \texttt{int *}) su cui sarà restituito il valore.
 \end{basedescript}
 
-% TODO aggiungere FIBMAP e FIEMAP, vedi http://lwn.net/Articles/260832
+% TODO aggiungere FIBMAP e FIEMAP, vedi http://lwn.net/Articles/260795/,
+% http://lwn.net/Articles/429345/ 
 
 Si noti però come la gran parte di queste operazioni specifiche dei file (per
 essere precisi le prime sei dell'elenco) siano effettuabili in maniera
@@ -1962,17 +2604,16 @@ molto simili e la presenza di questa sovrapposizione è principalmente dovuta
 al fatto che alle origini di Unix i progettisti considerarono che era
 necessario trattare diversamente rispetto alle operazione di controllo delle
 modalità di I/O file e dispositivi usando \func{fcntl} per i primi e
-\func{ioctl} per i secondi;\footnote{all'epoca tra l'altro i dispositivi che
-  usavano \func{ioctl} erano sostanzialmente solo i terminali, il che spiega
-  l'uso comune di \errcode{ENOTTY} come codice di errore.} oggi non è più così
-ma le due funzioni sono rimaste.
+\func{ioctl} per i secondi, all'epoca tra l'altro i dispositivi che usavano
+\func{ioctl} erano sostanzialmente solo i terminali, il che spiega l'uso
+comune di \errcode{ENOTTY} come codice di errore. Oggi non è più così ma le
+due funzioni sono rimaste.
 
 % TODO trovare qualche posto per la eventuale documentazione delle seguenti
 % (bassa/bassissima priorità)
 % EXT4_IOC_MOVE_EXT (dal 2.6.31)
-
-
-
+%  EXT4_IOC_SHUTDOWN (dal 4.10), XFS_IOC_GOINGDOWN e futura FS_IOC_SHUTDOWN
+% ioctl di btrfs, vedi http://lwn.net/Articles/580732/
 
 % \chapter{}
 
@@ -1985,12 +2626,11 @@ sono gestibili a basso livello con l'interfaccia standard unix, che ricorre
 direttamente alle \textit{system call} messe a disposizione dal kernel.
 
 Questa interfaccia però non provvede le funzionalità previste dallo standard
-ANSI C, che invece sono realizzate attraverso opportune funzioni di libreria,
-queste, insieme alle altre funzioni definite dallo standard, vengono a
-costituire il nucleo\footnote{queste funzioni sono state implementate la prima
-  volta da Ritchie nel 1976 e da allora sono rimaste sostanzialmente
-  immutate.} delle \acr{glibc}.
-
+ANSI C, che invece sono realizzate attraverso opportune funzioni di libreria.
+Queste funzioni di libreria, insieme alle altre funzioni definite dallo
+standard (che sono state implementate la prima volta da Ritchie nel 1976 e da
+allora sono rimaste sostanzialmente immutate), vengono a costituire il nucleo
+della \acr{glibc} per la gestione dei file.
 
 Esamineremo in questa sezione le funzioni base dell'interfaccia degli
 \textit{stream}, analoghe a quelle di sez.~\ref{sec:file_unix_interface} per i
@@ -2023,43 +2663,35 @@ operazioni di lettura e scrittura in blocchi di dimensioni appropriate
 all'ottenimento della massima efficienza.
 
 Per questo motivo l'interfaccia viene chiamata anche interfaccia dei
-\textit{file stream}, dato che non è più necessario doversi preoccupare
-dei dettagli della comunicazione con il tipo di hardware sottostante
-(come nel caso della dimensione dei blocchi del filesystem), ed un file
-può essere sempre considerato come composto da un flusso continuo (da
-cui il nome \textit{stream}) di dati.
+\textit{file stream}, dato che non è più necessario doversi preoccupare dei
+dettagli con cui viene gestita la comunicazione con l'hardware sottostante
+(come nel caso della dimensione dei blocchi del filesystem), ed un file può
+essere sempre considerato come composto da un flusso continuo di dati, da cui
+deriva appunto il nome \textit{stream}.
 
 A parte i dettagli legati alla gestione delle operazioni di lettura e
-scrittura (sia per quel che riguarda la bufferizzazione, che le
-formattazioni), i \textit{file stream} restano del tutto equivalenti ai file
-descriptor (sui quali sono basati), ed in particolare continua a valere quanto
-visto in sez.~\ref{sec:file_sharing} a proposito dell'accesso condiviso ed in
-sez.~\ref{sec:file_access_control} per il controllo di accesso.
-
-\itindend{file~stream}
-
-
-\subsection{Gli oggetti \type{FILE}}
-\label{sec:file_FILE}
-
+scrittura, sia per quel che riguarda la bufferizzazione che le formattazioni,
+per tutto il resto i \textit{file stream} restano del tutto equivalenti ai
+file descriptor (sui quali sono basati), ed in particolare continua a valere
+quanto visto in sez.~\ref{sec:file_shared_access} a proposito dell'accesso
+concorrente ed in sez.~\ref{sec:file_access_control} per il controllo di
+accesso.
 
 Per ragioni storiche la struttura di dati che rappresenta uno \textit{stream}
-è stata chiamata \type{FILE}, questi oggetti sono creati dalle funzioni di
+è stata chiamata \typed{FILE}, questi oggetti sono creati dalle funzioni di
 libreria e contengono tutte le informazioni necessarie a gestire le operazioni
 sugli \textit{stream}, come la posizione corrente, lo stato del buffer e degli
 indicatori di stato e di fine del file.
 
 Per questo motivo gli utenti non devono mai utilizzare direttamente o allocare
-queste strutture (che sono dei \index{tipo!opaco} \textsl{tipi opachi}) ma
-usare sempre puntatori del tipo \texttt{FILE *} ottenuti dalla libreria stessa
-(tanto che in certi casi il termine di puntatore a file è diventato sinonimo
-di \textit{stream}).  Tutte le funzioni della libreria che operano sui file
-accettano come argomenti solo variabili di questo tipo, che diventa
-accessibile includendo l'header file \headfile{stdio.h}.
-
+queste strutture (che sono dei \textsl{tipi opachi}) ma usare sempre puntatori
+del tipo \texttt{FILE *} ottenuti dalla libreria stessa, tanto che in certi
+casi il termine di puntatore a file è diventato sinonimo di \textit{stream}.
+Tutte le funzioni della libreria che operano sui file accettano come argomenti
+solo variabili di questo tipo, che diventa accessibile includendo l'header
+file \headfile{stdio.h}.
 
-\subsection{Gli \textit{stream standard}}
-\label{sec:file_std_stream}
+\itindend{file~stream}
 
 Ai tre file descriptor standard (vedi tab.~\ref{tab:file_std_files}) aperti
 per ogni processo, corrispondono altrettanti \textit{stream}, che
@@ -2102,78 +2734,75 @@ ma costituisce anche uno degli aspetti più comunemente fraintesi, in
 particolare per quello che riguarda l'aspetto della scrittura dei dati sul
 file.
 
-I caratteri che vengono scritti su di uno \textit{stream} normalmente vengono
-accumulati in un buffer e poi trasmessi in blocco\footnote{questa operazione
-  viene usualmente chiamata \textsl{scaricamento} dei dati, dal termine
-  inglese \textit{flush}.} tutte le volte che il buffer viene riempito, in
-maniera asincrona rispetto alla scrittura. Un comportamento analogo avviene
-anche in lettura (cioè dal file viene letto un blocco di dati, anche se ne
-sono richiesti una quantità inferiore), ma la cosa ovviamente ha rilevanza
-inferiore, dato che i dati letti sono sempre gli stessi. In caso di scrittura
-invece, quando si ha un accesso contemporaneo allo stesso file (ad esempio da
-parte di un altro processo) si potranno vedere solo le parti effettivamente
-scritte, e non quelle ancora presenti nel buffer.
+I dati che vengono scritti su di uno \textit{stream} normalmente vengono
+accumulati in un buffer e poi trasmessi in blocco, con l'operazione che viene
+usualmente chiamata \textsl{scaricamento} del buffer (dal termine inglese
+\textit{flush}) tutte le volte che questo viene riempito. Questa operazione
+avviene perciò in maniera asincrona rispetto alla scrittura. Un comportamento
+analogo avviene anche in lettura (cioè dal file viene letto un blocco di dati,
+anche se ne sono richiesti una quantità inferiore), ma la cosa ovviamente ha
+rilevanza inferiore, dato che i dati letti sono sempre gli stessi. In caso di
+scrittura invece, quando si ha un accesso contemporaneo allo stesso file (ad
+esempio da parte di un altro processo) si potranno vedere solo le parti
+effettivamente scritte, e non quelle ancora presenti nel buffer.
 
 Per lo stesso motivo, in tutte le situazioni in cui si sta facendo
 dell'input/output interattivo, bisognerà tenere presente le caratteristiche
 delle operazioni di scaricamento dei dati, poiché non è detto che ad una
 scrittura sullo \textit{stream} corrisponda una immediata scrittura sul
-dispositivo (la cosa è particolarmente evidente quando con le operazioni di
-input/output su terminale).
+dispositivo, e la cosa è particolarmente evidente con le operazioni di
+input/output sul terminale.
 
-Per rispondere ad esigenze diverse, lo standard definisce tre distinte
-modalità in cui può essere eseguita la bufferizzazione, delle quali
-occorre essere ben consapevoli, specie in caso di lettura e scrittura da
-dispositivi interattivi:
+Per rispondere ad esigenze diverse lo standard definisce tre distinte modalità
+in cui può essere eseguita la bufferizzazione, delle quali occorre essere ben
+consapevoli, specie in caso di lettura e scrittura da dispositivi interattivi:
 \begin{itemize}
 \item \textit{unbuffered}: in questo caso non c'è bufferizzazione ed i
   caratteri vengono trasmessi direttamente al file non appena possibile
-  (effettuando immediatamente una \func{write}).
-\item \textit{line buffered}: in questo caso i caratteri vengono
-  normalmente trasmessi al file in blocco ogni volta che viene
-  incontrato un carattere di \textit{newline} (il carattere ASCII
-  \verb|\n|).
+  (effettuando immediatamente una \func{write});
+\item \textit{line buffered}: in questo caso i caratteri vengono normalmente
+  trasmessi al file in blocco ogni volta che viene incontrato un carattere di
+  \textit{newline} (il carattere ASCII \verb|\n|) cioè un a capo (in sostanza
+  quando si preme invio);
 \item \textit{fully buffered}: in questo caso i caratteri vengono
   trasmessi da e verso il file in blocchi di dimensione opportuna.
 \end{itemize}
 
-Lo standard ANSI C specifica inoltre che lo standard output e lo
-standard input siano aperti in modalità \textit{fully buffered} quando
-non fanno riferimento ad un dispositivo interattivo, e che lo standard
+Lo standard ANSI C specifica inoltre che lo \textit{standard output} e lo
+\textit{standard input} siano aperti in modalità \textit{fully buffered}
+quando non fanno riferimento ad un dispositivo interattivo, e che lo standard
 error non sia mai aperto in modalità \textit{fully buffered}.
 
 Linux, come BSD e SVr4, specifica il comportamento predefinito in maniera
 ancora più precisa, e cioè impone che lo standard error sia sempre
-\textit{unbuffered} (in modo che i messaggi di errore siano mostrati il più
-rapidamente possibile) e che standard input e standard output siano aperti in
-modalità \textit{line buffered} quando sono associati ad un terminale (od
-altro dispositivo interattivo) ed in modalità \textit{fully buffered}
-altrimenti.
-
-Il comportamento specificato per standard input e standard output vale anche
-per tutti i nuovi \textit{stream} aperti da un processo; la selezione comunque
-avviene automaticamente, e la libreria apre lo \textit{stream} nella modalità
-più opportuna a seconda del file o del dispositivo scelto.
+\textit{unbuffered}, in modo che i messaggi di errore siano mostrati il più
+rapidamente possibile, e che \textit{standard input} \textit{standard output}
+siano aperti in modalità \textit{line buffered} quando sono associati ad un
+terminale (od altro dispositivo interattivo) ed in modalità \textit{fully
+  buffered} altrimenti.
+
+Il comportamento specificato per \textit{standard input} e \textit{standard
+  output} vale anche per tutti i nuovi \textit{stream} aperti da un processo;
+la selezione comunque avviene automaticamente, e la libreria apre lo
+\textit{stream} nella modalità più opportuna a seconda del file o del
+dispositivo scelto.
 
 La modalità \textit{line buffered} è quella che necessita di maggiori
 chiarimenti e attenzioni per quel che concerne il suo funzionamento. Come già
 accennato nella descrizione, \emph{di norma} i dati vengono inviati al kernel
-alla ricezione di un carattere di \textsl{a capo} (\textit{newline}); questo
-non è vero in tutti i casi, infatti, dato che le dimensioni del buffer usato
-dalle librerie sono fisse, se le si eccedono si può avere uno scarico dei dati
-anche prima che sia stato inviato un carattere di \textit{newline}.
+alla ricezione di un carattere di \textsl{a capo} (il \textit{newline});
+questo non è vero in tutti i casi, infatti, dato che le dimensioni del buffer
+usato dalle librerie sono fisse, se le si eccedono si può avere uno scarico
+dei dati anche prima che sia stato inviato un carattere di \textit{newline}.
 
 Un secondo punto da tenere presente, particolarmente quando si ha a che fare
 con I/O interattivo, è che quando si effettua una lettura da uno
-\textit{stream} che comporta l'accesso al kernel\footnote{questo vuol dire che
-  lo \textit{stream} da cui si legge è in modalità \textit{unbuffered}.} viene
-anche eseguito lo scarico di tutti i buffer degli \textit{stream} in
-scrittura.
-
-In sez.~\ref{sec:file_buffering_ctrl} vedremo come la libreria definisca delle
-opportune funzioni per controllare le modalità di bufferizzazione e lo scarico
-dei dati.
-
+\textit{stream} che comporta l'accesso alle \textit{system call} del kernel,
+ad esempio se lo \textit{stream} da cui si legge è in modalità
+\textit{unbuffered}, viene anche eseguito lo scarico di tutti i buffer degli
+\textit{stream} in scrittura. In sez.~\ref{sec:file_buffering_ctrl} vedremo
+come la libreria definisca delle opportune funzioni per controllare le
+modalità di bufferizzazione e lo scarico dei dati.
 
 
 
@@ -2183,42 +2812,43 @@ dei dati.
 Le funzioni che si possono usare per aprire uno \textit{stream} sono solo tre:
 \funcd{fopen}, \funcd{fdopen} e \funcd{freopen},\footnote{\func{fopen} e
   \func{freopen} fanno parte dello standard ANSI C, \func{fdopen} è parte
-  dello standard POSIX.1.} i loro prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h}
-  \funcdecl{FILE *fopen(const char *path, const char *mode)}
-  Apre il file specificato da \param{path}.
-  \funcdecl{FILE *fdopen(int fildes, const char *mode)}
-  Associa uno \textit{stream} al file descriptor \param{fildes}.
-  \funcdecl{FILE *freopen(const char *path, const char *mode, FILE *stream)}
-  Apre il file specificato da \param{path} associandolo allo \textit{stream}
-  specificato da \param{stream}, se questo è già aperto prima lo chiude.
-  
-  \bodydesc{Le funzioni ritornano un puntatore valido in caso di successo e
-    \val{NULL} in caso di errore, in tal caso \var{errno} assumerà il valore
-    ricevuto dalla funzione sottostante di cui è fallita l'esecuzione.
-  
-    Gli errori pertanto possono essere quelli di \func{malloc} per tutte
-    e tre le funzioni, quelli \func{open} per \func{fopen}, quelli di
-    \func{fcntl} per \func{fdopen} e quelli di \func{fopen},
-    \func{fclose} e \func{fflush} per \func{freopen}.}
-\end{functions}
+  dello standard POSIX.1.} ed i rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{FILE *fopen(const char *path, const char *mode)}
+\fdesc{Apre uno \textit{stream} da un \texttt{pathname}.} 
+\fdecl{FILE *fdopen(int fildes, const char *mode)}
+\fdesc{Associa uno \textit{stream} a un file descriptor.} 
+\fdecl{FILE *freopen(const char *path, const char *mode, FILE *stream)}
+\fdesc{Chiude uno \textit{stream} e lo riapre su un file diverso.} 
+}
+
+{Le funzioni ritornano un puntatore ad un oggetto \type{FILE} in caso di
+  successo e \val{NULL} per un errore, nel qual caso \var{errno} assumerà il
+  valore ricevuto dalla funzione sottostante di cui è fallita l'esecuzione,
+  gli errori pertanto possono essere quelli di \func{malloc} per tutte e tre
+  le funzioni, quelli \func{open} per \func{fopen}, quelli di \func{fcntl} per
+  \func{fdopen} e quelli di \func{fopen}, \func{fclose} e \func{fflush} per
+  \func{freopen}.}
+\end{funcproto}
 
 Normalmente la funzione che si usa per aprire uno \textit{stream} è
-\func{fopen}, essa apre il file specificato nella modalità specificata da
-\param{mode}, che è una stringa che deve iniziare con almeno uno dei valori
-indicati in tab.~\ref{tab:file_fopen_mode} (sono possibili varie estensioni
-che vedremo in seguito).
+\func{fopen}, essa apre il file specificato dal \textit{pathname} \param{path}
+nella modalità specificata da \param{mode}, che è una stringa che deve
+iniziare con almeno uno dei valori indicati in tab.~\ref{tab:file_fopen_mode},
+anche se sono possibili varie estensioni che vedremo in seguito.
 
-L'uso più comune di \func{freopen} è per redirigere uno dei tre file
-standard (vedi sez.~\ref{sec:file_std_stream}): il file \param{path} viene
-associato a \param{stream} e se questo è uno \textit{stream} già aperto viene
-preventivamente chiuso.
+L'uso più comune di \func{freopen} è per redirigere uno dei tre file standard
+(vedi sez.~\ref{sec:file_stream}): il file \param{path} viene aperto nella
+modalità indicata da \param{mode} ed associato allo \textit{stream} indicato
+dall'argomento \param{stream}, e se questo era uno \textit{stream} già aperto
+esso viene preventivamente chiuso e tutti i dati pendenti vengono scaricati.
 
 Infine \func{fdopen} viene usata per associare uno \textit{stream} ad un file
 descriptor esistente ottenuto tramite una altra funzione (ad esempio con una
 \func{open}, una \func{dup}, o una \func{pipe}) e serve quando si vogliono
-usare gli \textit{stream} con file come le fifo o i socket, che non possono
+usare gli \textit{stream} con file come le \textit{fifo} o i socket, che non possono
 essere aperti con le funzioni delle librerie standard del C.
 
 \begin{table}[htb]
@@ -2238,7 +2868,7 @@ essere aperti con le funzioni delle librerie standard del C.
 %    \hline
     \texttt{w} & Il file viene aperto e troncato a lunghezza nulla (o
                  creato se non esiste), l'accesso viene posto in sola
-                 scrittura, lo stream\textit{} è posizionato all'inizio del
+                 scrittura, lo \textit{stream} è posizionato all'inizio del
                  file.\\ 
     \texttt{w+}& Il file viene aperto e troncato a lunghezza nulla (o
                  creato se non esiste), l'accesso viene posto in scrittura e
@@ -2246,11 +2876,11 @@ essere aperti con le funzioni delle librerie standard del C.
                  file.\\ 
 %    \hline
     \texttt{a} & Il file viene aperto (o creato se non esiste) in
-                 \itindex{append~mode} \textit{append mode}, l'accesso viene
-                 posto in sola scrittura.\\
+                 \textit{append mode}, l'accesso viene posto in sola
+                 scrittura.\\
     \texttt{a+}& Il file viene aperto (o creato se non esiste) in
-                 \itindex{append~mode} \textit{append mode}, l'accesso viene
-                 posto in lettura e scrittura.\\
+                 \textit{append mode}, l'accesso viene posto in lettura e
+                 scrittura.\\
     \hline
     \texttt{b} & Specifica che il file è binario, non ha alcun effetto. \\
     \texttt{x} & L'apertura fallisce se il file esiste già. \\
@@ -2270,13 +2900,12 @@ distinguere i file binari dai file di testo; in un sistema POSIX questa
 distinzione non esiste e il valore viene accettato solo per
 compatibilità, ma non ha alcun effetto.
 
-Le \acr{glibc} supportano alcune estensioni, queste devono essere sempre
+La \acr{glibc} supporta alcune estensioni, queste devono essere sempre
 indicate dopo aver specificato il \param{mode} con uno dei valori di
 tab.~\ref{tab:file_fopen_mode}. L'uso del carattere \texttt{x} serve per
-evitare di sovrascrivere un file già esistente (è analoga all'uso
-dell'opzione \const{O\_EXCL} in \func{open}), se il file specificato già
-esiste e si aggiunge questo carattere a \param{mode} la \func{fopen}
-fallisce. 
+evitare di sovrascrivere un file già esistente (è analoga all'uso dell'opzione
+\const{O\_EXCL} in \func{open}): se il file specificato già esiste e si
+aggiunge questo carattere a \param{mode} la \func{fopen} fallisce.
 
 Un'altra estensione serve a supportare la localizzazione, quando si
 aggiunge a \param{mode} una stringa della forma \verb|",ccs=STRING"| il
@@ -2289,15 +2918,18 @@ essere compatibili con quelli con cui il file descriptor è stato aperto.
 Inoltre i modi \cmd{w} e \cmd{w+} non troncano il file. La posizione nello
 \textit{stream} viene impostata a quella corrente nel file descriptor, e le
 variabili di errore e di fine del file (vedi sez.~\ref{sec:file_io}) sono
-cancellate. Il file non viene duplicato e verrà chiuso alla chiusura dello
-\textit{stream}.
+cancellate. Il file non viene duplicato e verrà chiuso automaticamente alla
+chiusura dello \textit{stream}.
 
 I nuovi file saranno creati secondo quanto visto in
 sez.~\ref{sec:file_ownership_management} ed avranno i permessi di accesso
 impostati al valore
 \code{S\_IRUSR|S\_IWUSR|S\_IRGRP|S\_IWGRP|S\_IROTH|S\_IWOTH} (pari a
-\val{0666}) modificato secondo il valore di \itindex{umask} \textit{umask} per
-il processo (si veda sez.~\ref{sec:file_perm_management}).
+\val{0666}) modificato secondo il valore della \textit{umask} per il processo
+(si veda sez.~\ref{sec:file_perm_management}). Una volta aperto lo
+\textit{stream}, si può cambiare la modalità di bufferizzazione (si veda
+sez.~\ref{sec:file_buffering_ctrl}) fintanto che non si è effettuato alcuna
+operazione di I/O sul file.
 
 In caso di file aperti in lettura e scrittura occorre ricordarsi che c'è
 di mezzo una bufferizzazione; per questo motivo lo standard ANSI C
@@ -2314,82 +2946,98 @@ usare una delle funzioni \func{fseek}, \func{fsetpos} o \func{rewind}. Anche
 un'operazione nominalmente nulla come \code{fseek(file, 0, SEEK\_CUR)} è
 sufficiente a garantire la sincronizzazione.
 
-Una volta aperto lo \textit{stream}, si può cambiare la modalità di
-bufferizzazione (si veda sez.~\ref{sec:file_buffering_ctrl}) fintanto che non
-si è effettuato alcuna operazione di I/O sul file.
+Una volta completate le operazioni su di esso uno \textit{stream} può essere
+chiuso con la funzione \funcd{fclose}, il cui prototipo è:
 
-Uno \textit{stream} viene chiuso con la funzione \funcd{fclose} il cui
-prototipo è:
-\begin{prototype}{stdio.h}{int fclose(FILE *stream)}
-  Chiude lo \textit{stream} \param{stream}. 
-  
-  \bodydesc{Restituisce 0 in caso di successo e \val{EOF} in caso di errore,
-    nel qual caso imposta \var{errno} a \errval{EBADF} se il file descriptor
-    indicato da \param{stream} non è valido, o uno dei valori specificati
-    dalla sottostante funzione che è fallita (\func{close}, \func{write} o
-    \func{fflush}).}
-\end{prototype}
-
-La funzione effettua lo scarico di tutti i dati presenti nei buffer di uscita
-e scarta tutti i dati in ingresso; se era stato allocato un buffer per lo
-\textit{stream} questo verrà rilasciato. La funzione effettua lo scarico solo
-per i dati presenti nei buffer in user space usati dalle \acr{glibc}; se si
-vuole essere sicuri che il kernel forzi la scrittura su disco occorrerà
-effettuare una \func{sync} (vedi sez.~\ref{sec:file_sync}).
-
-Linux supporta anche una altra funzione, \funcd{fcloseall}, come estensione
-GNU implementata dalle \acr{glibc}, accessibile avendo definito
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int fclose(FILE *stream)}
+\fdesc{Chiude uno \textit{stream}.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e \val{EOF} per un errore, nel
+  qual caso \var{errno} assumerà il valore \errval{EBADF} se il file
+  descriptor indicato da \param{stream} non è valido, o uno dei valori
+  specificati dalla sottostante funzione che è fallita (\func{close},
+  \func{write} o \func{fflush}).
+}
+\end{funcproto}
+
+La funzione chiude lo \textit{stream} \param{stream} ed effettua lo scarico di
+tutti i dati presenti nei buffer di uscita e scarta tutti i dati in ingresso;
+se era stato allocato un buffer per lo \textit{stream} questo verrà
+rilasciato. La funzione effettua lo scarico solo per i dati presenti nei
+buffer in \textit{user space} usati dalla \acr{glibc}; se si vuole essere
+sicuri che il kernel forzi la scrittura su disco occorrerà effettuare una
+\func{sync} (vedi sez.~\ref{sec:file_sync}).
+
+Linux supporta anche un'altra funzione, \funcd{fcloseall}, come estensione
+GNU implementata dalla \acr{glibc}, accessibile avendo definito
 \macro{\_GNU\_SOURCE}, il suo prototipo è:
-\begin{prototype}{stdio.h}{int fcloseall(void)}
-  Chiude tutti gli \textit{stream}. 
-  
-  \bodydesc{Restituisce 0 se non ci sono errori ed \val{EOF} altrimenti.}
-\end{prototype}
-\noindent la funzione esegue lo scarico dei dati bufferizzati in uscita
-e scarta quelli in ingresso, chiudendo tutti i file. Questa funzione è
-provvista solo per i casi di emergenza, quando si è verificato un errore
-ed il programma deve essere abortito, ma si vuole compiere qualche altra
-operazione dopo aver chiuso i file e prima di uscire (si ricordi quanto
-visto in sez.~\ref{sec:proc_conclusion}).
-
-
-\subsection{Lettura e scrittura su uno \textit{stream}}
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int fcloseall(void)}
+\fdesc{Chiude tutti gli \textit{stream}.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e \val{EOF} per un errore, nel
+  qual caso \var{errno} assumerà gli stessi valori di \func{fclose}.}  
+\end{funcproto}
+
+La funzione esegue lo scarico dei dati bufferizzati in uscita e scarta quelli
+in ingresso, chiudendo tutti i file. Questa funzione è provvista solo per i
+casi di emergenza, quando si è verificato un errore ed il programma deve
+essere abortito, ma si vuole compiere qualche altra operazione dopo aver
+chiuso i file e prima di uscire (si ricordi quanto visto in
+sez.~\ref{sec:proc_conclusion}).
+
+
+\subsection{Gestione dell'I/O e posizionamento su uno \textit{stream}}
 \label{sec:file_io}
 
 Una delle caratteristiche più utili dell'interfaccia degli \textit{stream} è
 la ricchezza delle funzioni disponibili per le operazioni di lettura e
-scrittura sui file. Sono infatti previste ben tre diverse modalità modalità di
+scrittura sui file. Sono infatti previste ben tre diverse modalità di
 input/output non formattato:
-\begin{enumerate*}
-\item\textsl{binario} in cui legge/scrive un blocco di dati alla
-  volta, vedi sez.~\ref{sec:file_binary_io}.
-\item\textsl{a caratteri} in cui si legge/scrive un carattere alla
-  volta (con la bufferizzazione gestita automaticamente dalla libreria),
-  vedi sez.~\ref{sec:file_char_io}.
-\item\textsl{di linea} in cui si legge/scrive una linea alla volta (terminata
-  dal carattere di newline \verb|'\n'|), vedi sez.~\ref{sec:file_line_io}.
-\end{enumerate*}
-ed inoltre la modalità di input/output formattato.
-
-A differenza dell'interfaccia dei file descriptor, con gli \textit{stream} il
-raggiungimento della fine del file è considerato un errore, e viene
-notificato come tale dai valori di uscita delle varie funzioni. Nella
-maggior parte dei casi questo avviene con la restituzione del valore
-intero (di tipo \ctyp{int}) \val{EOF}\footnote{la costante deve essere
-  negativa, le \acr{glibc} usano -1, altre implementazioni possono avere
-  valori diversi.}  definito anch'esso nell'header \headfile{stdlib.h}.
+\begin{itemize}
+\item\textsl{binario} in cui si leggono e scrivono blocchi di dati di
+   dimensione arbitraria, (analogo della modalità ordinaria dell'I/O sui file
+   descriptor), trattato in sez.~\ref{sec:file_binary_io}.
+\item\textsl{a caratteri} in cui si legge e scrive un carattere alla volta,
+   con la bufferizzazione che viene gestita automaticamente dalla libreria,
+   trattato in sez.~\ref{sec:file_char_io}.
+\item\textsl{di linea} in cui si legge e scrive una linea alla volta,
+   (terminata dal carattere di newline \verb|'\n'|), trattato in
+   sez.~\ref{sec:file_line_io}.
+\end{itemize}
+a cui si aggiunge la modalità di input/output formattato, trattato in
+sez.~\ref{sec:file_formatted_io}.
+
+Ognuna di queste modalità utilizza per l'I/O delle funzioni specifiche che
+vedremo nelle sezioni citate, affronteremo qui tutte gli argomenti e le
+funzioni che si applicano in generale a tutte le modalità di I/O.
+
+A differenza di quanto avviene con l'interfaccia dei file descriptor, con gli
+\textit{stream} il raggiungimento della fine del file viene considerato un
+errore, e viene notificato come tale dai valori di uscita delle varie
+funzioni. Nella maggior parte dei casi questo avviene con la restituzione del
+valore intero (di tipo \ctyp{int}) \val{EOF} definito anch'esso nell'header
+\headfile{stdlib.h}. La costante deve essere negativa perché in molte funzioni
+un valore positivo indica la quantità di dati scritti, la \acr{glibc} usa il
+valore $-1$, ma altre implementazioni possono avere valori diversi.
 
 Dato che le funzioni dell'interfaccia degli \textit{stream} sono funzioni di
 libreria che si appoggiano a delle \textit{system call}, esse non impostano
-direttamente la variabile \var{errno}, che mantiene il valore impostato dalla
-\textit{system call} che ha riportato l'errore.
+direttamente la variabile \var{errno}, che mantiene sempre il valore impostato
+dalla \textit{system call} invocata internamente che ha riportato l'errore.
 
-Siccome la condizione di end-of-file è anch'essa segnalata come errore, nasce
-il problema di come distinguerla da un errore effettivo; basarsi solo sul
-valore di ritorno della funzione e controllare il valore di \var{errno}
-infatti non basta, dato che quest'ultimo potrebbe essere stato impostato in
-una altra occasione, (si veda sez.~\ref{sec:sys_errno} per i dettagli del
-funzionamento di \var{errno}).
+Siccome la condizione di \textit{end-of-file} è anch'essa segnalata come
+errore, nasce il problema di come distinguerla da un errore effettivo; basarsi
+solo sul valore di ritorno della funzione e controllare il valore di
+\var{errno} infatti non basta, dato che quest'ultimo potrebbe essere stato
+impostato in una altra occasione, (si veda sez.~\ref{sec:sys_errno} per i
+dettagli del funzionamento di \var{errno}).
 
 Per questo motivo tutte le implementazioni delle librerie standard mantengono
 per ogni \textit{stream} almeno due flag all'interno dell'oggetto \type{FILE},
@@ -2397,31 +3045,141 @@ il flag di \textit{end-of-file}, che segnala che si è raggiunta la fine del
 file in lettura, e quello di errore, che segnala la presenza di un qualche
 errore nelle operazioni di input/output; questi due flag possono essere
 riletti dalle funzioni \funcd{feof} e \funcd{ferror}, i cui prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h}
-  \funcdecl{int feof(FILE *stream)}
-  Controlla il flag di end-of-file di \param{stream}.
-  \funcdecl{int ferror(FILE *stream)}
-  Controlla il flag di errore di \param{stream}.
-  
-  \bodydesc{Entrambe le funzioni ritornano un valore diverso da zero se
-    i relativi flag sono impostati.}
-\end{functions}
-\noindent si tenga presente comunque che la lettura di questi flag segnala
-soltanto che c'è stato un errore, o che si è raggiunta la fine del file in una
-qualunque operazione sullo \textit{stream}, il controllo quindi deve essere
-effettuato ogni volta che si chiama una funzione di libreria.
-
-Entrambi i flag (di errore e di end-of-file) possono essere cancellati usando
-la funzione \funcd{clearerr}, il cui prototipo è:
-\begin{prototype}{stdio.h}{void clearerr(FILE *stream)}
-  Cancella i flag di errore ed \textit{end-of-file} di \param{stream}.
-\end{prototype}
-\noindent in genere si usa questa funzione una volta che si sia identificata e
-corretta la causa di un errore per evitare di mantenere i flag attivi, così da
-poter rilevare una successiva ulteriore condizione di errore. Di questa
-funzione esiste una analoga \funcm{clearerr\_unlocked} che non esegue il
-blocco dello \textit{stream} (vedi sez.~\ref{sec:file_stream_thread}).
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int feof(FILE *stream)}
+\fdesc{Controlla il flag di \textit{end-of-file} di uno \textit{stream}.} 
+\fdecl{int ferror(FILE *stream)}
+\fdesc{Controlla il flag di errore di uno \textit{stream}.} 
+}
+
+{Le funzioni ritornano un valore diverso da zero se i relativi flag sono
+  impostati, e non prevedono condizioni di errore.}
+\end{funcproto}
+
+Si tenga presente comunque che la lettura di questi flag segnala soltanto che
+c'è stato un errore o che si è raggiunta la fine del file in una qualunque
+operazione sullo \textit{stream}, il controllo su quanto avvenuto deve quindi
+essere effettuato ogni volta che si chiama una funzione di libreria.
+
+Entrambi i flag (di errore e di \textit{end-of-file}) possono essere
+cancellati usando la funzione \funcd{clearerr}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{void clearerr(FILE *stream)}
+\fdesc{Cancella i flag di errore ed \textit{end-of-file} di uno
+  \textit{stream}.}
+}
+
+{La funzione non ritorna nulla e prevede condizioni di errore.}  
+\end{funcproto}
+
+In genere si usa questa funzione una volta che si sia identificata e corretta
+la causa di un errore per evitare di mantenere i flag attivi, così da poter
+rilevare una successiva ulteriore condizione di errore. Di questa funzione
+esiste una analoga \funcm{clearerr\_unlocked} (con lo stesso argomento e
+stessi valori di ritorno) che non esegue il blocco dello \textit{stream}
+(tratteremo il significato di blocco di uno \textit{stream} in
+sez.~\ref{sec:file_stream_thread}).
+
+Come per i file descriptor anche per gli \textit{stream} è possibile spostarsi
+all'interno di un file per effettuare operazioni di lettura o scrittura in un
+punto prestabilito, sempre che l'operazione di riposizionamento sia supportata
+dal file sottostante lo \textit{stream}, nel caso cioè in cui si ha a che fare
+con quello che viene detto un file ad \textsl{accesso casuale}. Dato che in un
+sistema Unix esistono vari tipi di file, come le \textit{fifo} ed i file di
+dispositivo (ad esempio i terminali), non è scontato che questo sia vero in
+generale, pur essendolo sempre nel caso di file di dati.
+
+Con Linux ed in generale in ogni sistema unix-like la posizione nel file, come
+abbiamo già visto in sez.~\ref{sec:file_lseek}, è espressa da un intero
+positivo, rappresentato dal tipo \type{off\_t}. Il problema è che alcune delle
+funzioni usate per il riposizionamento sugli \textit{stream} originano dalle
+prime versioni di Unix, in cui questo tipo non era ancora stato definito, e
+che in altri sistemi non è detto che la posizione su un file venga sempre
+rappresentata con il numero di caratteri dall'inizio: ad esempio nel VMS dove
+esistono i file a record (in cui cioè l'I/O avviene per blocchi, i record, di
+dimensione fissa), essa può essere rappresentata come un numero di record, più
+l'offset rispetto al record corrente.
+
+Tutto questo comporta la presenza di diverse funzioni che eseguono
+sostanzialmente le stesse operazioni, ma usano argomenti di tipo diverso. Le
+funzioni tradizionali usate per eseguire una modifica della posizione corrente
+sul file con uno \textit{stream} sono \funcd{fseek} e \funcd{rewind}, i
+rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int fseek(FILE *stream, long offset, int whence)}
+\fdesc{Sposta la posizione nello \textit{stream}.} 
+\fdecl{void rewind(FILE *stream)}
+\fdesc{Riporta la posizione nello \textit{stream} all'inizio del file.} 
+}
+
+{La funzione \func{fseek} ritorna $0$ in caso di successo e $-1$ per un
+  errore, nel qual caso \var{errno} assumerà i valori di \func{lseek},
+  \func{rewind} non ritorna nulla e non ha condizioni di errore.}
+\end{funcproto}
+
+L'uso di \func{fseek} è del tutto analogo a quello di \func{lseek} per i file
+descriptor (vedi sez.~\ref{sec:file_lseek}). Anche gli argomenti, a parte il
+tipo, hanno esattamente lo stesso significato. In particolare \param{whence}
+deve assumere gli stessi valori già visti nella prima parte di
+tab.~\ref{tab:lseek_whence_values}.  La funzione restituisce 0 in caso di
+successo e -1 in caso di errore.
+
+La funzione \func{rewind} riporta semplicemente la posizione corrente sul file
+all'inizio dello \textit{stream}, ma non è esattamente equivalente ad aver
+eseguito una \code{fseek(stream, 0L, SEEK\_SET)}, in quanto con l'uso della
+funzione vengono cancellati anche i flag di errore e di fine del file.
+
+Per ottenere la posizione corrente sul file di uno \textit{stream} lo standard
+ANSI C prescrive l'uso della funzione \funcd{ftell}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{long ftell(FILE *stream)} 
+\fdesc{Legge la posizione attuale nello \textit{stream}.} 
+}
+
+{La funzione ritorna la posizione corrente in caso di successo e $-1$ per un
+  errore, nel qual caso \var{errno} assumerà  i valori di \func{lseek}.}  
+\end{funcproto}
+
+\noindent che restituisce la posizione come numero di byte dall'inizio dello
+\textit{stream}.
+
+Sia \func{fseek} che \func{ftell} esprimono la posizione nel file con un
+intero di tipo \ctyp{long}. Dato che in certi casi, ad esempio quando si usa
+un filesystem indicizzato a 64 bit su una macchina con architettura a 32 bit,
+questo può non essere possibile lo standard POSIX ha introdotto le nuove
+funzioni \funcd{fgetpos} e \funcd{fsetpos}, che invece usano il nuovo tipo
+\typed{fpos\_t}, ed i cui prototipi sono:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int fsetpos(FILE *stream, fpos\_t *pos)}
+\fdesc{Imposta la posizione corrente sul file.} 
+\fdecl{int fgetpos(FILE *stream, fpos\_t *pos)}
+\fdesc{Legge la posizione corrente sul file.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà i valori di \func{lseek}.}
+\end{funcproto}
+
+In Linux, a partire dalle glibc 2.1, sono presenti anche le due funzioni
+\func{fseeko} e \func{ftello}, che sono assolutamente identiche alle
+precedenti \func{fseek} e \func{ftell} ma hanno argomenti di tipo
+\type{off\_t} anziché di tipo \ctyp{long int}. Dato che \ctyp{long} è nella
+gran parte dei casi un intero a 32 bit, questo diventa un problema quando la
+posizione sul file viene espressa con un valore a 64 bit come accade nei
+sistemi più moderni.
+
+% TODO: mettere prototipi espliciti fseeko e ftello o menzione?
+
 
 
 \subsection{Input/output binario}
@@ -2432,28 +3190,28 @@ interfaccia dei file descriptor, e provvede semplicemente la scrittura e la
 lettura dei dati da un buffer verso un file e viceversa. In generale questa è
 la modalità che si usa quando si ha a che fare con dati non formattati. Le due
 funzioni che si usano per l'I/O binario sono \funcd{fread} ed \funcd{fwrite};
-i loro prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h} 
-  
-  \funcdecl{size\_t fread(void *ptr, size\_t size, size\_t nmemb, FILE
-    *stream)}
-  
-  \funcdecl{size\_t fwrite(const void *ptr, size\_t size, size\_t
-    nmemb, FILE *stream)}
-  
-  Rispettivamente leggono e scrivono \param{nmemb} elementi di dimensione
-  \param{size} dal buffer \param{ptr} al file \param{stream}.
-  
-  \bodydesc{Entrambe le funzioni ritornano il numero di elementi letti o
-    scritti, in caso di errore o fine del file viene restituito un numero di
-    elementi inferiore al richiesto.}
-\end{functions}
-
-In genere si usano queste funzioni quando si devono trasferire su file
-blocchi di dati binari in maniera compatta e veloce; un primo caso di uso
-tipico è quello in cui si salva un vettore (o un certo numero dei suoi
-elementi) con una chiamata del tipo:
+i rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{stdio.h} 
+\fdecl{size\_t fread(void *ptr, size\_t size, size\_t nmemb, FILE *stream)}
+\fdesc{Legge i dati da uno \textit{stream}.} 
+\fdecl{size\_t fwrite(const void *ptr, size\_t size, size\_t nmemb, 
+  FILE *stream)}
+\fdesc{Scrive i dati su uno \textit{stream}.} 
+}
+
+{Le funzioni ritornano il numero di elementi letti o scritti, in caso di
+  errore o fine del file viene restituito un numero di elementi inferiore al
+  richiesto.}
+\end{funcproto}
+
+Le funzioni rispettivamente leggono e scrivono \param{nmemb} elementi di
+dimensione \param{size} dal buffer \param{ptr} al file \param{stream}.  In
+genere si usano queste funzioni quando si devono trasferire su file blocchi di
+dati binari in maniera compatta e veloce; un primo caso di uso tipico è quello
+in cui si salva un vettore (o un certo numero dei suoi elementi) con una
+chiamata del tipo:
 \includecodesnip{listati/WriteVect.c}
 in questo caso devono essere specificate le dimensioni di ciascun
 elemento ed il numero di quelli che si vogliono scrivere. Un secondo
@@ -2464,9 +3222,9 @@ in cui si specifica la dimensione dell'intera struttura ed un solo
 elemento. 
 
 In realtà quello che conta nel trasferimento dei dati sono le dimensioni
-totali, che sono sempre pari al prodotto \code{size * nelem}; la sola
-differenza è che le funzioni non ritornano il numero di byte scritti,
-ma il numero di elementi.
+totali, che sono sempre pari al prodotto \code{size * nelem}, la differenza
+sta nel fatto che le funzioni non ritornano il numero di byte scritti, ma il
+numero di elementi (e con questo possono facilitare i conti).
 
 La funzione \func{fread} legge sempre un numero intero di elementi, se
 incontra la fine del file l'oggetto letto parzialmente viene scartato (lo
@@ -2497,30 +3255,32 @@ di architettura hardware, come la dimensione del bus o la modalità di
 ordinamento dei bit o il formato delle variabili in floating point.
 
 Per questo motivo quando si usa l'input/output binario occorre sempre prendere
-le opportune precauzioni (in genere usare un formato di più alto livello che
-permetta di recuperare l'informazione completa), per assicurarsi che versioni
-diverse del programma siano in grado di rileggere i dati tenendo conto delle
+le opportune precauzioni come usare un formato di più alto livello che
+permetta di recuperare l'informazione completa, per assicurarsi che versioni
+diverse del programma siano in grado di rileggere i dati, tenendo conto delle
 eventuali differenze.
 
-Le \acr{glibc} definiscono altre due funzioni per l'I/O binario,
-\funcd{fread\_unlocked} e \funcd{fwrite\_unlocked} che evitano il lock
-implicito dello \textit{stream}, usato per dalla librerie per la gestione delle
-applicazioni \itindex{thread} \textit{multi-thread} (si veda
-sez.~\ref{sec:file_stream_thread} per i dettagli), i loro prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h}
-  
-  \funcdecl{size\_t fread\_unlocked(void *ptr, size\_t size, size\_t
+La \acr{glibc} definisce infine due ulteriori funzioni per l'I/O binario,
+\funcd{fread\_unlocked} e \funcd{fwrite\_unlocked}, che evitano il lock
+implicito dello \textit{stream} usato per dalla librerie per la gestione delle
+applicazioni \textit{multi-thread} (si veda sez.~\ref{sec:file_stream_thread}
+per i dettagli), i loro prototipi sono:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{size\_t fread\_unlocked(void *ptr, size\_t size, size\_t
     nmemb, FILE *stream)}
-  
-  \funcdecl{size\_t fwrite\_unlocked(const void *ptr, size\_t size,
+\fdecl{size\_t fwrite\_unlocked(const void *ptr, size\_t size,
     size\_t nmemb, FILE *stream)}
-  
-  \bodydesc{Le funzioni sono identiche alle analoghe \func{fread} e
-    \func{fwrite} ma non acquisiscono il lock implicito sullo \textit{stream}.}
-\end{functions}
-\noindent entrambe le funzioni sono estensioni GNU previste solo dalle
-\acr{glibc}.
+\fdesc{Leggono o scrivono dati su uno \textit{stream} senza acquisire il lock
+  implicito sullo stesso.} 
+}
+
+{Le funzioni ritornano gli stessi valori delle precedenti \func{fread} e
+  \func{fwrite}.}
+\end{funcproto}
+
+% TODO: trattare in generale le varie *_unlocked
 
 
 \subsection{Input/output a caratteri}
@@ -2528,23 +3288,26 @@ sez.~\ref{sec:file_stream_thread} per i dettagli), i loro prototipi sono:
 
 La seconda modalità di input/output è quella a caratteri, in cui si
 trasferisce un carattere alla volta.  Le funzioni per la lettura a
-caratteri sono tre, \funcd{fgetc}, \funcd{getc} e \funcd{getchar}, i
+caratteri sono tre, \funcd{fgetc}, \funcd{getc} e \funcd{getchar}, ed i
 rispettivi prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h} 
-
-  \funcdecl{int getc(FILE *stream)} Legge un byte da \param{stream} e lo
-  restituisce come intero. In genere è implementata come una macro. 
-  
-  \funcdecl{int fgetc(FILE *stream)} Legge un byte da \param{stream} e lo
-  restituisce come intero. È sempre una funzione.
-  
-  \funcdecl{int getchar(void)} Equivalente a \code{getc(stdin)}.
-  
-  \bodydesc{Tutte queste funzioni leggono un byte alla volta, che viene
-    restituito come intero; in caso di errore o fine del file il valore
-    di ritorno è \val{EOF}.}
-\end{functions}
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int getc(FILE *stream)}
+\fdecl{int fgetc(FILE *stream)}
+\fdesc{Leggono un singolo byte da uno \textit{stream}.} 
+\fdecl{int getchar(void)}
+\fdesc{Legge un byte dallo \textit{standard input}.} 
+}
+
+{Le funzioni ritornano il byte letto in caso di successo e \val{EOF} per un
+  errore o se si arriva alla fine del file.}  
+\end{funcproto}
+
+La funzione \func{getc} legge un byte da \param{stream} e lo restituisce come
+intero, ed in genere è implementata come una macro per cui può avere
+\textit{side effects}, mentre \func{fgetc} è assicurato essere sempre una
+funzione. Infine \func{getchar} è equivalente a \code{getc(stdin)}.
 
 A parte \func{getchar}, che si usa in genere per leggere un carattere da
 tastiera, le altre due funzioni sono sostanzialmente equivalenti. La
@@ -2571,48 +3334,54 @@ funzioni equivalenti alle precedenti, \funcd{getwc}, \funcd{fgetwc} e
 \funcd{getwchar}, che invece di un carattere di un byte restituiscono un
 carattere in formato esteso (cioè di tipo \ctyp{wint\_t}), il loro prototipo
 è:
-\begin{functions}
-  \headdecl{stdio.h} 
-  \headdecl{wchar.h} 
-  
-  \funcdecl{wint\_t getwc(FILE *stream)} Legge un carattere esteso da
-  \param{stream}. In genere è implementata come una macro.
-  
-  \funcdecl{wint\_t fgetwc(FILE *stream)} Legge un carattere esteso da
-  \param{stream}. È una sempre una funzione.
-  
-  \funcdecl{wint\_t getwchar(void)} Equivalente a \code{getwc(stdin)}.
-  
-  \bodydesc{Tutte queste funzioni leggono un carattere alla volta, in
-    caso di errore o fine del file il valore di ritorno è \const{WEOF}.}
-\end{functions}
+
+\begin{funcproto}{
+\fhead{stdio.h} 
+\fhead{wchar.h}
+\fdecl{wint\_t getwc(FILE *stream)}
+\fdecl{wint\_t fgetwc(FILE *stream)}
+\fdesc{Leggono un carattere da uno \textit{stream}.} 
+\fdecl{wint\_t getwchar(void)}
+\fdesc{Legge un carattere dallo \textit{standard input}.} 
+}
+
+{Le funzioni ritornano il carattere letto in caso di successo e \val{WEOF} per
+  un errore o se si arriva alla fine del file.}  
+\end{funcproto}
+
+La funzione \func{getwc} legge un carattere esteso da \param{stream} e lo
+restituisce come intero, ed in genere è implementata come una macro, mentre
+\func{fgetwc} è assicurata essere sempre una funzione. Infine \func{getwchar}
+è equivalente a \code{getwc(stdin)}.
 
 Per scrivere un carattere si possono usare tre funzioni, analoghe alle
 precedenti usate per leggere: \funcd{putc}, \funcd{fputc} e \funcd{putchar}; i
 loro prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h} 
-  
-  \funcdecl{int putc(int c, FILE *stream)} Scrive il carattere \param{c}
-  su \param{stream}. In genere è implementata come una macro.
-  
-  \funcdecl{int fputc(int c, FILE *stream)} Scrive il carattere \param{c} su
-  \param{stream}. È una sempre una funzione.
-  
-  \funcdecl{int putchar(int c)} Equivalente a \code{putc(stdout)}.
-  
-  \bodydesc{Le funzioni scrivono sempre un carattere alla volta, il cui
-    valore viene restituito in caso di successo; in caso di errore o
-    fine del file il valore di ritorno è \val{EOF}.}
-\end{functions}
-
-Tutte queste funzioni scrivono sempre un byte alla volta, anche se prendono
-come argomento un \ctyp{int} (che pertanto deve essere ottenuto con un cast da
-un \ctyp{unsigned char}). Anche il valore di ritorno è sempre un intero; in
-caso di errore o fine del file il valore di ritorno è \val{EOF}.
-
-Come nel caso dell'I/O binario con \func{fread} e \func{fwrite} le \acr{glibc}
-provvedono come estensione, per ciascuna delle funzioni precedenti,
+
+\begin{funcproto}{
+\fhead{stdio.h} 
+\fdecl{int putc(int c, FILE *stream)}
+\fdecl{int fputc(int c, FILE *stream)}
+\fdesc{Scrive un byte su uno \textit{stream}.}
+\fdecl{int putchar(int c)}
+\fdesc{Scrive un byte sullo \textit{standard output}.}
+}
+
+{Le funzioni ritornano il valore del byte scritto in caso di successo e
+  \val{EOF} per un errore.}  
+\end{funcproto}
+
+La funzione \func{putc} scrive un byte su \param{stream} e lo restituisce come
+intero, ed in genere è implementata come una macro, mentre \func{fputc} è
+assicurata essere sempre una funzione. Infine \func{putchar} è equivalente a
+\code{putc(stdout)}.  Tutte queste funzioni scrivono sempre un byte alla
+volta, anche se prendono come argomento un \ctyp{int} (che pertanto deve
+essere ottenuto con un cast da un \ctyp{unsigned char}). Anche il valore di
+ritorno è sempre un intero; in caso di errore o fine del file il valore di
+ritorno è \val{EOF}.
+
+Come nel caso dell'I/O binario con \func{fread} e \func{fwrite} la \acr{glibc}
+provvede come estensione, per ciascuna delle funzioni precedenti,
 un'ulteriore funzione, il cui nome è ottenuto aggiungendo un
 \code{\_unlocked}, che esegue esattamente le stesse operazioni, evitando però
 il lock implicito dello \textit{stream}.
@@ -2620,16 +3389,18 @@ il lock implicito dello \textit{stream}.
 Per compatibilità con SVID sono inoltre provviste anche due funzioni,
 \funcd{getw} e \funcd{putw}, da usare per leggere e scrivere una \textit{word}
 (cioè due byte in una volta); i loro prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h} 
-  
-  \funcdecl{int getw(FILE *stream)} Legge una parola da \param{stream}.
-  \funcdecl{int putw(int w, FILE *stream)} Scrive la parola \param{w} su
-  \param{stream}.
-  
-  \bodydesc{Le funzioni restituiscono la parola \param{w}, o \val{EOF}
-    in caso di errore o di fine del file.}
-\end{functions}
+
+\begin{funcproto}{
+\fhead{stdio.h} 
+\fdecl{getw(FILE *stream)}
+\fdesc{Legge una parola da uno \textit{stream}.} 
+\fdecl{int putw(int w, FILE *stream)}
+\fdesc{Scrive una parola su uno \textit{stream}.} 
+}
+
+{Le funzioni ritornano la parola letta o scritta in caso di successo e
+  \val{EOF} per un errore.}
+\end{funcproto}
 
 Le funzioni leggono e scrivono una \textit{word} di due byte, usando comunque
 una variabile di tipo \ctyp{int}; il loro uso è deprecato in favore dell'uso
@@ -2647,147 +3418,163 @@ Nel nostro caso questo tipo di comportamento può essere realizzato prima
 leggendo il carattere, e poi rimandandolo indietro, cosicché ridiventi
 disponibile per una lettura successiva; la funzione che inverte la
 lettura si chiama \funcd{ungetc} ed il suo prototipo è:
-\begin{prototype}{stdio.h}{int ungetc(int c, FILE *stream)}
-  Rimanda indietro il carattere \param{c}, con un cast a \ctyp{unsigned
-    char}, sullo \textit{stream} \param{stream}.
-
-  \bodydesc{La funzione ritorna \param{c} in caso di successo e
-  \val{EOF} in caso di errore.}
-\end{prototype}
-\noindent benché lo standard ANSI C preveda che l'operazione possa
-essere ripetuta per un numero arbitrario di caratteri, alle
-implementazioni è richiesto di garantire solo un livello; questo è
-quello che fa la \acr{glibc}, che richiede che avvenga un'altra
-operazione fra due \func{ungetc} successive.
 
-Non è necessario che il carattere che si manda indietro sia l'ultimo che
-si è letto, e non è necessario neanche avere letto nessun carattere
-prima di usare \func{ungetc}, ma di norma la funzione è intesa per
-essere usata per rimandare indietro l'ultimo carattere letto.
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int ungetc(int c, FILE *stream)}
+\fdesc{Manda indietro un byte su uno \textit{stream}.} 
+}
+
+{La funzione ritorna il byte inviato in caso di successo e \val{EOF} per un
+  errore.}  
+\end{funcproto}
+La funzione rimanda indietro il carattere \param{c}, con un cast a
+\ctyp{unsigned char}, sullo \textit{stream} \param{stream}. Benché lo standard
+ANSI C preveda che l'operazione possa essere ripetuta per un numero arbitrario
+di caratteri, alle implementazioni è richiesto di garantire solo un livello;
+questo è quello che fa la \acr{glibc}, che richiede che avvenga un'altra
+operazione fra due \func{ungetc} successive.
 
-Nel caso \param{c} sia un \val{EOF} la funzione non fa nulla, e
-restituisce sempre \val{EOF}; così si può usare \func{ungetc} anche
-con il risultato di una lettura alla fine del file.
+Non è necessario che il carattere che si manda indietro sia l'ultimo che si è
+letto, e non è necessario neanche avere letto nessun carattere prima di usare
+\func{ungetc}, ma di norma la funzione è intesa per essere usata per rimandare
+indietro l'ultimo carattere letto.  Nel caso \param{c} sia un \val{EOF} la
+funzione non fa nulla, e restituisce sempre \val{EOF}; così si può usare
+\func{ungetc} anche con il risultato di una lettura alla fine del file.
 
-Se si è alla fine del file si può comunque rimandare indietro un
-carattere, il flag di end-of-file verrà automaticamente cancellato
-perché c'è un nuovo carattere disponibile che potrà essere riletto
-successivamente.
+Se si è alla fine del file si può comunque rimandare indietro un carattere, il
+flag di \textit{end-of-file} verrà automaticamente cancellato perché c'è un
+nuovo carattere disponibile che potrà essere riletto successivamente.
 
-Infine si tenga presente che \func{ungetc} non altera il contenuto del
-file, ma opera esclusivamente sul buffer interno. Se si esegue una
-qualunque delle operazioni di riposizionamento (vedi
-sez.~\ref{sec:file_fseek}) i caratteri rimandati indietro vengono
-scartati.
+Infine si tenga presente che \func{ungetc} non altera il contenuto del file,
+ma opera esclusivamente sul buffer interno. Se si esegue una qualunque delle
+operazioni di riposizionamento (vedi sez.~\ref{sec:file_io}) i caratteri
+rimandati indietro vengono scartati.
 
 
 \subsection{Input/output di linea}
 \label{sec:file_line_io}
 
 La terza ed ultima modalità di input/output non formattato è quella di linea,
-in cui si legge o si scrive una riga alla volta; questa è una modalità molto
-usata per l'I/O da terminale, ma è anche quella che presenta le
+in cui si legge o si scrive una riga alla volta. Questa è la modalità usata
+normalmente per l'I/O da terminale, ed è anche quella che presenta le
 caratteristiche più controverse.
 
 Le funzioni previste dallo standard ANSI C per leggere una linea sono
 sostanzialmente due, \funcd{gets} e \funcd{fgets}, i cui rispettivi
 prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h} 
-  
-  \funcdecl{char *gets(char *string)} Scrive su \param{string} una
-  linea letta da \var{stdin}.
-  
-  \funcdecl{char *fgets(char *string, int size, FILE *stream)}
-  Scrive su \param{string} la linea letta da \param{stream} per un
-  massimo di \param{size} byte.
-  
-  \bodydesc{Le funzioni restituiscono l'indirizzo \param{string} in caso
-    di successo o \val{NULL} in caso di errore.}
-\end{functions}
-
-Entrambe le funzioni effettuano la lettura (dal file specificato \func{fgets},
-dallo standard input \func{gets}) di una linea di caratteri (terminata dal
-carattere \textit{newline}, \verb|'\n'|, quello mappato sul tasto di ritorno a
-capo della tastiera), ma \func{gets} sostituisce \verb|'\n'| con uno zero,
-mentre \func{fgets} aggiunge uno zero dopo il \textit{newline}, che resta
-dentro la stringa. Se la lettura incontra la fine del file (o c'è un errore)
-viene restituito un \val{NULL}, ed il buffer \param{buf} non viene toccato.
-L'uso di \func{gets} è deprecato e deve essere assolutamente evitato; la
-funzione infatti non controlla il numero di byte letti, per cui nel caso la
-stringa letta superi le dimensioni del buffer, si avrà un
-\itindex{buffer~overflow} \textit{buffer overflow}, con sovrascrittura della
-memoria del processo adiacente al buffer.\footnote{questa tecnica è spiegata
-  in dettaglio e con molta efficacia nell'ormai famoso articolo di Aleph1
-  \cite{StS}.}
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{char *gets(char *string)}
+\fdesc{Legge una linea di testo dallo \textit{standard input}.}
+\fdecl{char *fgets(char *string, int size, FILE *stream)}
+\fdesc{Legge una linea di testo da uno \textit{stream}.} 
+}
+
+{Le funzioni ritornano l'indirizzo della stringa con la linea di testo letta o
+  scritta in caso di successo e \val{NULL} per un errore.}
+\end{funcproto}
+Entrambe le funzioni effettuano la lettura, dal file specificato \func{fgets},
+dallo \textit{standard input} \func{gets}, di una linea di caratteri terminata
+dal carattere ASCII di \textit{newline}, che come detto corrisponde a quello
+generato dalla pressione del tasto di invio sulla tastiera. Si tratta del
+carattere che indica la terminazione di una riga (in sostanza del carattere di
+``\textsl{a capo}'') che viene rappresentato nelle stringhe di formattazione
+che vedremo in sez.~\ref{sec:file_formatted_io} come
+``\verb|\n|''. Nell'esecuzione delle funzioni \func{gets} sostituisce
+``\verb|\n|'' con uno zero, mentre \func{fgets} aggiunge uno zero dopo il
+\textit{newline}, che resta dentro la stringa.
+
+\itindbeg{buffer~overflow}
+
+Se la lettura incontra la fine del file (o c'è un errore) viene restituito un
+puntatore \val{NULL}, ed il buffer \param{buf} non viene toccato.  L'uso di
+\func{gets} è deprecato e deve essere assolutamente evitato, la funzione
+infatti non controlla il numero di byte letti, per cui nel caso la stringa
+letta superi le dimensioni del buffer, si avrà un \textit{buffer overflow},
+con sovrascrittura della memoria del processo adiacente al
+buffer.\footnote{questa tecnica è spiegata in dettaglio e con molta efficacia
+  nell'ormai famoso articolo di Aleph1 \cite{StS}.}
 
 Questa è una delle vulnerabilità più sfruttate per guadagnare accessi non
 autorizzati al sistema (i cosiddetti \textit{exploit}), basta infatti inviare
 una stringa sufficientemente lunga ed opportunamente forgiata per
-sovrascrivere gli indirizzi di ritorno nello \itindex{stack} \textit{stack}
-(supposto che la \func{gets} sia stata chiamata da una subroutine), in modo da
-far ripartire l'esecuzione nel codice inviato nella stringa stessa (in genere
-uno \textit{shell code} cioè una sezione di programma che lancia una shell).
+sovrascrivere gli indirizzi di ritorno nello \textit{stack} (supposto che la
+\func{gets} sia stata chiamata da una subroutine), in modo da far ripartire
+l'esecuzione nel codice inviato nella stringa stessa, che in genere contiene
+uno \textit{shell code}, cioè una sezione di programma che lancia una shell da
+cui si potranno poi eseguire altri programmi.
+
+\itindend{buffer~overflow}
 
 La funzione \func{fgets} non ha i precedenti problemi di \func{gets} in quanto
-prende in input la dimensione del buffer \param{size}, che non verrà mai
+prende in ingresso la dimensione del buffer \param{size}, che non verrà mai
 ecceduta in lettura. La funzione legge fino ad un massimo di \param{size}
-caratteri (newline compreso), ed aggiunge uno zero di terminazione; questo
-comporta che la stringa possa essere al massimo di \code{size-1} caratteri.  Se
-la linea eccede la dimensione del buffer verranno letti solo \code{size-1}
-caratteri, ma la stringa sarà sempre terminata correttamente con uno zero
-finale; sarà possibile leggere i rimanenti caratteri in una chiamata
+caratteri (\textit{newline} compreso), ed aggiunge uno zero di terminazione;
+questo comporta che la stringa possa essere al massimo di \code{size-1}
+caratteri.  Se la linea eccede la dimensione del buffer verranno letti solo
+\code{size-1} caratteri, ma la stringa sarà sempre terminata correttamente con
+uno zero finale; sarà possibile leggere i rimanenti caratteri in una chiamata
 successiva.
 
 Per la scrittura di una linea lo standard ANSI C prevede altre due
 funzioni, \funcd{fputs} e \funcd{puts}, analoghe a quelle di lettura, i
 rispettivi prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h} 
-  
-  \funcdecl{int puts(const char *string)} Scrive su \var{stdout} la
-  linea \param{string}.
-  
-  \funcdecl{int fputs(const char *string, FILE *stream)} Scrive su
-  \param{stream} la linea \param{string}.
-  
-  \bodydesc{Le funzioni restituiscono un valore non negativo in caso di
-    successo o \val{EOF} in caso di errore.}
-\end{functions}
-
-Dato che in questo caso si scrivono i dati in uscita \func{puts} non ha i
-problemi di \func{gets} ed è in genere la forma più immediata per scrivere
-messaggi sullo standard output; la funzione prende una stringa terminata da
-uno zero ed aggiunge automaticamente il ritorno a capo. La differenza con
-\func{fputs} (a parte la possibilità di specificare un file diverso da
-\var{stdout}) è che quest'ultima non aggiunge il newline, che deve essere
-previsto esplicitamente.
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int puts(char *string)}
+\fdesc{Scrive una linea di testo sullo \textit{standard output}.}
+\fdecl{int fputs(char *string, int size, FILE *stream)}
+\fdesc{Scrive una linea di testo su uno \textit{stream}.} 
+}
+
+{Le funzioni ritornano un valore non negativo in caso di successo e \val{EOF}
+  per un errore.}
+\end{funcproto}
+
+La funzione \func{puts} scrive una linea di testo mantenuta
+all'indirizzo \param{string} sullo \textit{standard output} mentre \func{puts}
+la scrive sul file indicato da \param{stream}.  Dato che in questo caso si
+scrivono i dati in uscita \func{puts} non ha i problemi di \func{gets} ed è in
+genere la forma più immediata per scrivere messaggi sullo \textit{standard
+  output}; la funzione prende una stringa terminata da uno zero ed aggiunge
+automaticamente il ritorno a capo. La differenza con \func{fputs} (a parte la
+possibilità di specificare un file diverso da \var{stdout}) è che quest'ultima
+non aggiunge il \textit{newline}, che deve essere previsto esplicitamente.
 
 Come per le analoghe funzioni di input/output a caratteri, anche per l'I/O di
 linea esistono delle estensioni per leggere e scrivere linee di caratteri
 estesi, le funzioni in questione sono \funcd{fgetws} e \funcd{fputws} ed i
 loro prototipi sono:
-\begin{functions}
-  \headdecl{wchar.h} 
-  \funcdecl{wchar\_t *fgetws(wchar\_t *ws, int n, FILE *stream)}
-  Legge un massimo di \param{n} caratteri estesi dal file
-  \param{stream} al buffer \param{ws}.
-  
-  \funcdecl{int fputws(const wchar\_t *ws, FILE *stream)} Scrive la
-  linea \param{ws} di caratteri estesi sul file \param{stream}.
-  
-  \bodydesc{Le funzioni ritornano rispettivamente \param{ws} o un numero
-    non negativo in caso di successo e \val{NULL} o \val{EOF} in
-    caso di errore o fine del file.}
-\end{functions}
-
-Il comportamento di queste due funzioni è identico a quello di \func{fgets} e
-\func{fputs}, a parte il fatto che tutto (numero di caratteri massimo,
-terminatore della stringa, newline) è espresso in termini di caratteri estesi
-anziché di normali caratteri ASCII.
-
-Come per l'I/O binario e quello a caratteri, anche per l'I/O di linea le
-\acr{glibc} supportano una serie di altre funzioni, estensioni di tutte quelle
+
+\begin{funcproto}{
+\fhead{wchar.h}
+\fdecl{wchar\_t *fgetws(wchar\_t *ws, int n, FILE *stream)}
+\fdesc{Legge una stringa di carattere estesi da uno \textit{stream}.} 
+\fdecl{int fputws(const wchar\_t *ws, FILE *stream)}
+\fdesc{Scrive una stringa di carattere estesi da uno \textit{stream}.} 
+}
+
+{Le funzioni ritornano rispettivamente l'indirizzo della stringa o un non
+  negativo in caso di successo e \val{NULL} o \val{EOF} per un errore o per la
+  fine del file.}
+\end{funcproto}
+
+
+La funzione \func{fgetws} legge un massimo di \param{n} caratteri estesi dal
+file \param{stream} al buffer \param{ws}, mentre la funzione \func{fputws}
+scrive la linea \param{ws} di caratteri estesi sul file indicato
+da \param{stream}.  Il comportamento di queste due funzioni è identico a
+quello di \func{fgets} e \func{fputs}, a parte il fatto che tutto (numero di
+caratteri massimo, terminatore della stringa, \textit{newline}) è espresso in
+termini di caratteri estesi anziché di normali caratteri ASCII.
+
+Come per l'I/O binario e quello a caratteri, anche per l'I/O di linea la
+\acr{glibc} supporta una serie di altre funzioni, estensioni di tutte quelle
 illustrate finora (eccetto \func{gets} e \func{puts}), che eseguono
 esattamente le stesse operazioni delle loro equivalenti, evitando però il lock
 implicito dello \textit{stream} (vedi sez.~\ref{sec:file_stream_thread}). Come
@@ -2796,49 +3583,52 @@ analoga normale, con l'aggiunta dell'estensione \code{\_unlocked}.
 
 Come abbiamo visto, le funzioni di lettura per l'input/output di linea
 previste dallo standard ANSI C presentano svariati inconvenienti. Benché
-\func{fgets} non abbia i gravissimi problemi di \func{gets}, può
-comunque dare risultati ambigui se l'input contiene degli zeri; questi
-infatti saranno scritti sul buffer di uscita e la stringa in output
-apparirà come più corta dei byte effettivamente letti. Questa è una
-condizione che è sempre possibile controllare (deve essere presente un
-newline prima della effettiva conclusione della stringa presente nel
-buffer), ma a costo di una complicazione ulteriore della logica del
-programma. Lo stesso dicasi quando si deve gestire il caso di stringa
-che eccede le dimensioni del buffer.
-
-Per questo motivo le \acr{glibc} prevedono, come estensione GNU, due nuove
+\func{fgets} non abbia i gravissimi problemi di \func{gets}, può comunque dare
+risultati ambigui se l'input contiene degli zeri; questi infatti saranno
+scritti sul buffer di uscita e la stringa in output apparirà come più corta
+dei byte effettivamente letti. Questa è una condizione che è sempre possibile
+controllare (deve essere presente un \textit{newline} prima della effettiva
+conclusione della stringa presente nel buffer), ma a costo di una
+complicazione ulteriore della logica del programma. Lo stesso dicasi quando si
+deve gestire il caso di stringa che eccede le dimensioni del buffer.
+
+Per questo motivo la \acr{glibc} prevede, come estensione GNU, due nuove
 funzioni per la gestione dell'input/output di linea, il cui uso permette di
 risolvere questi problemi. L'uso di queste funzioni deve essere attivato
 definendo la macro \macro{\_GNU\_SOURCE} prima di includere
 \headfile{stdio.h}. La prima delle due, \funcd{getline}, serve per leggere una
-linea terminata da un newline, esattamente allo stesso modo di \func{fgets},
-il suo prototipo è:
-\begin{prototype}{stdio.h}
-  {ssize\_t getline(char **buffer, size\_t *n, FILE *stream)} Legge una linea
-  dal file \param{stream} copiandola sul buffer indicato da \param{buffer}
-  riallocandolo se necessario (l'indirizzo del buffer e la sua dimensione
-  vengono sempre riscritte).
-
-  \bodydesc{La funzione ritorna il numero di caratteri letti in caso di
-  successo e -1 in caso di errore o di raggiungimento della fine del
-  file.}
-\end{prototype}
-
-La funzione permette di eseguire una lettura senza doversi preoccupare della
-eventuale lunghezza eccessiva della stringa da leggere. Essa prende come primo
-argomento l'indirizzo del puntatore al buffer su cui si vuole copiare la
-linea. Quest'ultimo \emph{deve} essere stato allocato in precedenza con una
-\func{malloc} (non si può passare l'indirizzo di un puntatore ad una variabile
-locale); come secondo argomento la funzione vuole l'indirizzo della variabile
-contenente le dimensioni del buffer suddetto.
+linea terminata da un \textit{newline}, esattamente allo stesso modo di
+\func{fgets}, il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{ssize\_t getline(char **buffer, size\_t *n, FILE *stream)}
+\fdesc{Legge una riga da uno \textit{stream}.} 
+}
+
+{La funzione ritorna il numero di caratteri letti in caso di successo e $-1$
+  per un errore o per il raggiungimento della fine del file.}
+\end{funcproto}
+
+La funzione legge una linea dal file \param{stream} copiandola sul buffer
+indicato da \param{buffer} riallocandolo se necessario (l'indirizzo del buffer
+e la sua dimensione vengono sempre riscritte). Permette così di eseguire una
+lettura senza doversi preoccupare della eventuale lunghezza eccessiva della
+stringa da leggere. 
+
+Essa prende come primo argomento l'indirizzo del puntatore al buffer su cui si
+vuole copiare la linea. Quest'ultimo \emph{deve} essere stato allocato in
+precedenza con una \func{malloc}, non si può cioè passare come argomento primo
+argomento l'indirizzo di un puntatore ad una variabile locale. Come secondo
+argomento la funzione vuole l'indirizzo della variabile contenente le
+dimensioni del buffer suddetto.
 
 Se il buffer di destinazione è sufficientemente ampio la stringa viene scritta
 subito, altrimenti il buffer viene allargato usando \func{realloc} e la nuova
-dimensione ed il nuovo puntatore vengono restituiti indietro (si noti infatti
-come per entrambi gli argomenti si siano usati dei
-\itindex{value~result~argument} \textit{value result argument}, passando dei
-puntatori anziché i valori delle variabili, secondo la tecnica spiegata in
-sez.~\ref{sec:proc_var_passing}).
+dimensione ed il nuovo puntatore vengono restituiti indietro, si noti infatti
+come entrambi gli argomenti siano dei \textit{value result argument}, per i
+quali vengono passati dei puntatori anziché i valori delle variabili, secondo
+quanto abbiamo descritto in sez.~\ref{sec:proc_var_passing}).
 
 Se si passa alla funzione l'indirizzo di un puntatore impostato a \val{NULL} e
 \var{*n} è zero, la funzione provvede da sola all'allocazione della memoria
@@ -2846,31 +3636,41 @@ necessaria a contenere la linea. In tutti i casi si ottiene dalla funzione un
 puntatore all'inizio del testo della linea letta. Un esempio di codice può
 essere il seguente: 
 \includecodesnip{listati/getline.c} 
-e per evitare  \itindex{memory~leak} \textit{memory leak} occorre ricordarsi di
-liberare \var{ptr} con una \func{free}.
-
-Il valore di ritorno della funzione indica il numero di caratteri letti
-dallo \textit{stream} (quindi compreso il newline, ma non lo zero di
-terminazione); questo permette anche di distinguere eventuali zeri letti
-dallo \textit{stream} da quello inserito dalla funzione per terminare la linea.
-Se si è alla fine del file e non si è potuto leggere nulla o c'è stato
-un errore la funzione restituisce -1.
-
-La seconda estensione GNU è una generalizzazione di \func{getline} per
-poter usare come separatore un carattere qualsiasi, la funzione si
-chiama \funcd{getdelim} ed il suo prototipo è:
-\begin{prototype}{stdio.h}
-{ssize\_t getdelim(char **buffer, size\_t *n, int delim, FILE *stream)} 
-  Identica a \func{getline} solo che usa \param{delim} al posto del
-  carattere di newline come separatore di linea.
-\end{prototype}
-
-Il comportamento di \func{getdelim} è identico a quello di \func{getline} (che
-può essere implementata da questa passando \verb|'\n'| come valore di
-\param{delim}).
-
-
-\subsection{L'input/output formattato}
+e per evitare \textit{memory leak} occorre ricordarsi di liberare la memoria
+allocata dalla funzione eseguendo una \func{free} su \var{ptr}.
+
+Il valore di ritorno di \func{getline} indica il numero di caratteri letti
+dallo \textit{stream}, quindi compreso il \textit{newline}, ma non lo zero di
+terminazione. Questo permette anche di distinguere anche gli eventuali zeri
+letti come dati dallo \textit{stream} da quello inserito dalla funzione dopo
+il \textit{newline} per terminare la stringa.  Se si è alla fine del file e
+non si è potuto leggere nulla o se c'è stato un errore la funzione restituisce
+$-1$.
+
+La seconda estensione GNU per la lettura con l'I/O di linea è una
+generalizzazione di \func{getline} per poter usare come separatore delle linee
+un carattere qualsiasi al posto del \textit{newline}. La funzione si chiama
+\funcd{getdelim} ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{size\_t getdelim(char **buffer, size\_t *n, int delim, FILE *stream)} 
+\fdesc{Legge da uno \textit{stream} una riga delimitata da un carattere
+  scelto.} 
+}
+
+{La funzione ha gli stessi valori di ritorno e gli stessi errori di
+  \func{getline}.}
+\end{funcproto}
+
+La funzione è identica a \func{getline} solo che usa \param{delim} al posto
+del carattere di \textit{newline} come separatore di linea. Il comportamento
+di \func{getdelim} è identico a quello di \func{getline}, che può essere
+implementata da \func{getdelim} passando ``\verb|\n|'' come valore
+dell'argomento \param{delim}.
+
+
+\subsection{Input/output formattato}
 \label{sec:file_formatted_io}
 
 L'ultima modalità di input/output è quella formattata, che è una delle
@@ -2881,43 +3681,49 @@ permette di stampare in maniera facile e veloce dati, tabelle e messaggi.
 L'output formattato viene eseguito con una delle 13 funzioni della famiglia
 \func{printf}; le tre più usate sono \funcd{printf}, \funcd{fprintf} e
 \funcd{sprintf}, i cui prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h} 
-  \funcdecl{int printf(const char *format, ...)} Stampa su \file{stdout}
-  gli argomenti, secondo il formato specificato da \param{format}.
-  
-  \funcdecl{int fprintf(FILE *stream, const char *format, ...)}  Stampa
-  su \param{stream} gli argomenti, secondo il formato specificato da
-  \param{format}.
-  
-  \funcdecl{int sprintf(char *str, const char *format, ...)} Stampa
-  sulla stringa \param{str} gli argomenti, secondo il formato
-  specificato da \param{format}.
-
-  \bodydesc{Le funzioni ritornano il numero di caratteri stampati.}
-\end{functions}
-\noindent le prime due servono per stampare su file (lo standard output o
-quello specificato) la terza permette di stampare su una stringa, in genere
+
+\begin{funcproto}{
+\fhead{stdio.h} 
+\fdecl{int printf(const char *format, ...)}
+\fdesc{Scrive una stringa formattata sullo \textit{standard output}.}
+\fdecl{int fprintf(FILE *stream, const char *format, ...)}
+\fdesc{Scrive una stringa formattata su uno \textit{stream}.} 
+\fdecl{int sprintf(char *str, const char *format, ...)} 
+\fdesc{Scrive una stringa formattata su un buffer.} 
+}
+
+{Le funzioni ritornano il numero di caratteri scritti in caso di successo e un
+  valore negativo per un errore.}  
+\end{funcproto}
+
+
+Le funzioni usano la stringa \param{format} come indicatore del formato con
+cui dovrà essere scritto il contenuto degli argomenti, il cui numero è
+variabile e dipende dal formato stesso.
+
+Le prime due servono per scrivere su file (lo \textit{standard output} o
+quello specificato) la terza permette di scrivere su una stringa, in genere
 l'uso di \func{sprintf} è sconsigliato in quanto è possibile, se non si ha la
 sicurezza assoluta sulle dimensioni del risultato della stampa, eccedere le
 dimensioni di \param{str}, con conseguente sovrascrittura di altre variabili e
-possibili \itindex{buffer~overflow} \textit{buffer overflow}; per questo
-motivo si consiglia l'uso dell'alternativa \funcd{snprintf}, il cui prototipo
-è:
-\begin{prototype}{stdio.h}
-{snprintf(char *str, size\_t size, const char *format, ...)} 
-  Identica a \func{sprintf}, ma non scrive su \param{str} più di
-  \param{size} caratteri.
-\end{prototype}
+possibili \textit{buffer overflow}. Per questo motivo si consiglia l'uso
+dell'alternativa \funcd{snprintf}, il cui prototipo è:
 
-La parte più complessa delle funzioni di scrittura formattata è il formato
-della stringa \param{format} che indica le conversioni da fare, e da cui
-deriva anche il numero degli argomenti che dovranno essere passati a seguire
-(si noti come tutte queste funzioni siano \index{funzioni!variadic}
-\textit{variadic}, prendendo un numero di argomenti variabile che dipende
-appunto da quello che si è specificato in \param{format}).
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{snprintf(char *str, size\_t size, const char *format, ...)} 
+\fdesc{Scrive una stringa formattata su un buffer.} 
+}
 
-\begin{table}[htb]
+{La funzione ha lo stesso valore di ritorno e gli stessi errori di
+  \func{sprintf}.}
+\end{funcproto}
+
+\noindent la funzione è identica a \func{sprintf}, ma non scrive
+su \param{str} più di \param{size} caratteri, garantendo così che il buffer
+non possa essere sovrascritto.
+
+\begin{table}[!htb]
   \centering
   \footnotesize
   \begin{tabular}[c]{|l|l|p{10cm}|}
@@ -2927,7 +3733,7 @@ appunto da quello che si è specificato in \param{format}).
     \hline
    \cmd{\%d} &\ctyp{int}         & Stampa un numero intero in formato decimale
                                    con segno.\\
-   \cmd{\%i} &\ctyp{int}         & Identico a \cmd{\%i} in output.\\
+   \cmd{\%i} &\ctyp{int}         & Identico a \cmd{\%d} in output.\\
    \cmd{\%o} &\ctyp{unsigned int}& Stampa un numero intero come ottale.\\
    \cmd{\%u} &\ctyp{unsigned int}& Stampa un numero intero in formato
                                    decimale senza segno.\\
@@ -2953,7 +3759,7 @@ appunto da quello che si è specificato in \param{format}).
    \cmd{\%s} &\ctyp{char *} & Stampa una stringa.\\
    \cmd{\%p} &\ctyp{void *} & Stampa il valore di un puntatore.\\
    \cmd{\%n} &\ctyp{\&int}  & Prende il numero di caratteri stampati finora.\\
-   \cmd{\%\%}&              & Stampa un \%.\\
+   \cmd{\%\%}&              & Stampa un ``\texttt{\%}''.\\
     \hline
   \end{tabular}
   \caption{Valori possibili per gli specificatori di conversione in una
@@ -2961,11 +3767,41 @@ appunto da quello che si è specificato in \param{format}).
   \label{tab:file_format_spec}
 \end{table}
 
-La stringa è costituita da caratteri normali (tutti eccetto \texttt{\%}), che
-vengono passati invariati all'output, e da direttive di conversione, in cui
-devono essere sempre presenti il carattere \texttt{\%}, che introduce la
-direttiva, ed uno degli specificatori di conversione (riportati in
-tab.~\ref{tab:file_format_spec}) che la conclude.
+La parte più complessa delle funzioni di scrittura formattata è il formato
+della stringa \param{format} che indica le conversioni da fare, e da cui
+deriva anche il numero degli argomenti che dovranno essere passati a seguire:
+si noti come tutte queste funzioni siano ``\textit{variadic}'', prendendo un
+numero di argomenti variabile che dipende appunto da quello che si è
+specificato in \param{format}.
+
+La stringa di formato è costituita da caratteri normali (tutti eccetto
+``\texttt{\%}''), che vengono passati invariati in uscita, e da direttive di
+conversione, in cui devono essere sempre presenti il carattere
+``\texttt{\%}'', che introduce la direttiva, ed uno degli specificatori di
+conversione (riportati in tab.~\ref{tab:file_format_spec}) che la conclude.
+
+Il formato di una direttiva di conversione prevede una serie di possibili
+elementi opzionali oltre al carattere ``\cmd{\%}'' e allo specificatore di
+conversione. In generale essa è sempre del tipo:
+\begin{Example}
+% [n. parametro $] [flag] [[larghezza] [. precisione]] [tipo] conversione
+\end{Example}
+in cui tutti i valori tranne il ``\texttt{\%}'' e lo specificatore di
+conversione sono opzionali (e per questo sono indicati fra parentesi quadre);
+si possono usare più elementi opzionali, nel qual caso devono essere
+specificati in questo ordine:
+\begin{itemize*}
+\item uno specificatore del parametro da usare (terminato da un carattere
+  ``\val{\$}''),
+\item uno o più flag (i cui valori possibili sono riassunti in
+  tab.~\ref{tab:file_format_flag}) che controllano il formato di stampa della
+  conversione,
+\item uno specificatore di larghezza (un numero decimale), eventualmente
+  seguito (per i numeri in virgola mobile) da un specificatore di precisione
+  (un altro numero decimale),
+\item uno specificatore del tipo di dato, che ne indica la dimensione (i cui
+  valori possibili sono riassunti in tab.~\ref{tab:file_format_type}).
+\end{itemize*}
 
 \begin{table}[htb]
   \centering
@@ -2975,7 +3811,7 @@ tab.~\ref{tab:file_format_spec}) che la conclude.
     \textbf{Valore} & \textbf{Significato}\\
     \hline
     \hline
-    \val{\#} & Chiede la conversione in forma alternativa. \\
+    \val{\#} & Chiede la conversione in forma alternativa.\\
     \val{0}  & La conversione è riempita con zeri alla sinistra del valore.\\
     \val{-}  & La conversione viene allineata a sinistra sul bordo del campo.\\
     \val{' '}& Mette uno spazio prima di un numero con segno di valore 
@@ -2987,33 +3823,9 @@ tab.~\ref{tab:file_format_spec}) che la conclude.
   \label{tab:file_format_flag}
 \end{table}
 
-Il formato di una direttiva di conversione prevede una serie di possibili
-elementi opzionali oltre al \cmd{\%} e allo specificatore di conversione. In
-generale essa è sempre del tipo:
-\begin{center}
-\begin{verbatim}
-% [n. parametro $] [flag] [[larghezza] [. precisione]] [tipo] conversione
-\end{verbatim}
-\end{center}
-in cui tutti i valori tranne il \val{\%} e lo specificatore di conversione
-sono opzionali (e per questo sono indicati fra parentesi quadre); si possono
-usare più elementi opzionali, nel qual caso devono essere specificati in
-questo ordine:
-\begin{itemize*}
-\item uno specificatore del parametro da usare (terminato da un \val{\$}),
-\item uno o più flag (i cui valori possibili sono riassunti in
-  tab.~\ref{tab:file_format_flag}) che controllano il formato di stampa della
-  conversione,
-\item uno specificatore di larghezza (un numero decimale), eventualmente
-  seguito (per i numeri in virgola mobile) da un specificatore di precisione
-  (un altro numero decimale),
-\item uno specificatore del tipo di dato, che ne indica la dimensione (i cui
-  valori possibili sono riassunti in tab.~\ref{tab:file_format_type}).
-\end{itemize*}
-
-
-Dettagli ulteriori sulle varie opzioni possono essere trovati nella pagina di
-manuale di \func{printf} e nella documentazione delle \acr{glibc}.
+Dettagli ulteriori sulle varie opzioni di stampa e su tutte le casistiche
+dettagliate dei vari formati possono essere trovati nella pagina di manuale di
+\func{printf} e nella documentazione della \acr{glibc}.
 
 \begin{table}[htb]
   \centering
@@ -3039,11 +3851,11 @@ manuale di \func{printf} e nella documentazione delle \acr{glibc}.
     \cmd{L}  & Una conversione in virgola mobile corrisponde a un
                \ctyp{double}.\\
     \cmd{q}  & Sinonimo di \cmd{ll}.\\
-    \cmd{j}  & Una conversione intera corrisponde a un \type{intmax\_t} o 
-               \type{uintmax\_t}.\\
-    \cmd{z}  & Una conversione intera corrisponde a un \type{size\_t} o 
-               \type{ssize\_t}.\\
-    \cmd{t}  & Una conversione intera corrisponde a un \type{ptrdiff\_t}.\\
+    \cmd{j}  & Una conversione intera corrisponde a un \ctyp{intmax\_t} o 
+               \ctyp{uintmax\_t}.\\
+    \cmd{z}  & Una conversione intera corrisponde a un \ctyp{size\_t} o 
+               \ctyp{ssize\_t}.\\
+    \cmd{t}  & Una conversione intera corrisponde a un \ctyp{ptrdiff\_t}.\\
     \hline
   \end{tabular}
   \caption{Il modificatore di tipo di dato per il formato di \func{printf}}
@@ -3051,75 +3863,74 @@ manuale di \func{printf} e nella documentazione delle \acr{glibc}.
 \end{table}
 
 Una versione alternativa delle funzioni di output formattato, che permettono
-di usare il puntatore ad una lista variabile \index{funzioni!variadic} di
-argomenti (vedi sez.~\ref{sec:proc_variadic}), sono \funcd{vprintf},
-\funcd{vfprintf} e \funcd{vsprintf}, i cui prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h} 
-  
-  \funcdecl{int vprintf(const char *format, va\_list ap)} Stampa su
-  \var{stdout} gli argomenti della lista \param{ap}, secondo il formato
-  specificato da \param{format}.
-  
-  \funcdecl{int vfprintf(FILE *stream, const char *format, va\_list ap)}
-  Stampa su \param{stream} gli argomenti della lista \param{ap}, secondo il
-  formato specificato da \param{format}.
-  
-  \funcdecl{int vsprintf(char *str, const char *format, va\_list ap)} Stampa
-  sulla stringa \param{str} gli argomenti della lista \param{ap}, secondo il
-  formato specificato da \param{format}.
-
-  \bodydesc{Le funzioni ritornano il numero di caratteri stampati.}
-\end{functions}
-\noindent con queste funzioni diventa possibile selezionare gli argomenti che
-si vogliono passare ad una funzione di stampa, passando direttamente la lista
+di usare il puntatore ad una lista variabile di argomenti (vedi
+sez.~\ref{sec:proc_variadic}), sono \funcd{vprintf}, \funcd{vfprintf} e
+\funcd{vsprintf}, i cui prototipi sono:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int vprintf(const char *format, va\_list ap)}
+\fdesc{Scrive una stringa formattata sullo \textit{standard output}.} 
+\fdecl{int vfprintf(FILE *stream, const char *format, va\_list ap)}
+\fdesc{Scrive una stringa formattata su uno \textit{stream}.}
+\fdecl{int vsprintf(char *str, const char *format, va\_list ap)}
+\fdesc{Scrive una stringa formattata su un buffer.}
+}
+
+{Le funzioni ritornano il numero di caratteri scritti in caso di successo e un
+  valore negativo per un errore.}  
+\end{funcproto}
+
+Con queste funzioni diventa possibile selezionare gli argomenti che si
+vogliono passare ad una funzione di stampa, passando direttamente la lista
 tramite l'argomento \param{ap}. Per poter far questo ovviamente la lista
-variabile\index{funzioni!variadic} degli argomenti dovrà essere opportunamente
-trattata (l'argomento è esaminato in sez.~\ref{sec:proc_variadic}), e dopo
-l'esecuzione della funzione l'argomento
-\param{ap} non sarà più utilizzabile (in generale dovrebbe essere eseguito un
-\code{va\_end(ap)} ma in Linux questo non è necessario). 
+variabile degli argomenti dovrà essere opportunamente trattata (l'argomento è
+esaminato in sez.~\ref{sec:proc_variadic}), e dopo l'esecuzione della funzione
+l'argomento \param{ap} non sarà più utilizzabile (in generale dovrebbe essere
+eseguito un \code{va\_end(ap)} ma in Linux questo non è necessario).
 
 Come per \func{sprintf} anche per \func{vsprintf} esiste una analoga
 \funcd{vsnprintf} che pone un limite sul numero di caratteri che vengono
 scritti sulla stringa di destinazione:
-\begin{prototype}{stdio.h}
-{vsnprintf(char *str, size\_t size, const char *format, va\_list ap)} 
-  Identica a \func{vsprintf}, ma non scrive su \param{str} più di
-  \param{size} caratteri.
-\end{prototype}
-\noindent in modo da evitare possibili \itindex{buffer~overflow} buffer
-overflow.
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{vsnprintf(char *str, size\_t size, const char *format, va\_list ap)}
+\fdesc{Scrive una stringa formattata su un buffer.} 
+}
+
+{La funzione ha lo stesso valore di ritorno e gli stessi errori di
+  \func{vsprintf}.}
+\end{funcproto}
+
+\noindent in modo da evitare possibili \textit{buffer overflow}.
 
 
-Per eliminare alla radice questi problemi, le \acr{glibc} supportano una
+Per eliminare alla radice questi problemi, la \acr{glibc} supporta una
 specifica estensione GNU che alloca dinamicamente tutto lo spazio necessario;
 l'estensione si attiva al solito definendo \macro{\_GNU\_SOURCE}, le due
 funzioni sono \funcd{asprintf} e \funcd{vasprintf}, ed i rispettivi prototipi
 sono:
-\begin{functions}
-  \headdecl{stdio.h} 
-    
-  \funcdecl{int asprintf(char **strptr, const char *format, ...)}  Stampa gli
-  argomenti specificati secondo il formato specificato da \param{format} su
-  una stringa allocata automaticamente all'indirizzo \param{*strptr}.
-  
-  \funcdecl{int vasprintf(char **strptr, const char *format, va\_list ap)}
-  Stampa gli argomenti della lista \param{ap} secondo il formato specificato
-  da \param{format} su una stringa allocata automaticamente all'indirizzo
-  \param{*strptr}.
-
-  \bodydesc{Le funzioni ritornano il numero di caratteri stampati.}
-\end{functions}
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int asprintf(char **strptr, const char *format, ...)}
+\fdecl{int vasprintf(char **strptr, const char *format, va\_list ap)}
+\fdesc{Scrive una stringa formattata su un buffer.} 
+}
+
+{Le funzioni hanno lo stesso valore di ritorno e gli stessi errori di
+  \func{vsprintf}.}
+\end{funcproto}
+
 
 Entrambe le funzioni prendono come argomento \param{strptr} che deve essere
 l'indirizzo di un puntatore ad una stringa di caratteri, in cui verrà
 restituito (si ricordi quanto detto in sez.~\ref{sec:proc_var_passing} a
-proposito dei \itindex{value~result~argument} \textit{value result argument})
-l'indirizzo della stringa allocata automaticamente dalle funzioni. Occorre
-inoltre ricordarsi di invocare \func{free} per liberare detto puntatore quando
-la stringa non serve più, onde evitare \itindex{memory~leak} \textit{memory
-  leak}.
+proposito dei \textit{value result argument}) l'indirizzo della stringa
+allocata automaticamente dalle funzioni. Occorre inoltre ricordarsi di
+invocare \func{free} per liberare detto puntatore quando la stringa non serve
+più, onde evitare \textit{memory leak}.
 
 % TODO verificare se mettere prototipi di \func{dprintf} e \func{vdprintf}
 
@@ -3128,32 +3939,37 @@ Infine una ulteriore estensione GNU definisce le due funzioni \funcm{dprintf} e
 \textit{stream}. Altre estensioni permettono di scrivere con caratteri
 estesi. Anche queste funzioni, il cui nome è generato dalle precedenti
 funzioni aggiungendo una \texttt{w} davanti a \texttt{print}, sono trattate in
-dettaglio nella documentazione delle \acr{glibc}.
+dettaglio nella documentazione della \acr{glibc}.
 
 In corrispondenza alla famiglia di funzioni \func{printf} che si usano per
 l'output formattato, l'input formattato viene eseguito con le funzioni della
 famiglia \func{scanf}; fra queste le tre più importanti sono \funcd{scanf},
 \funcd{fscanf} e \funcd{sscanf}, i cui prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h} \funcdecl{int scanf(const char *format, ...)} Esegue una
-  scansione di \file{stdin} cercando una corrispondenza di quanto letto con il
-  formato dei dati specificato da \param{format}, ed effettua le relative
-  conversione memorizzando il risultato negli argomenti seguenti.
-  
-  \funcdecl{int fscanf(FILE *stream, const char *format, ...)}  Analoga alla
-  precedente, ma effettua la scansione su \param{stream}.
-  
-  \funcdecl{int sscanf(char *str, const char *format, ...)} Analoga alle
-  precedenti, ma effettua la scansione dalla stringa \param{str}.
-  
-  \bodydesc{Le funzioni ritornano il numero di elementi assegnati. Questi
-    possono essere in numero inferiore a quelli specificati, ed anche zero.
-    Quest'ultimo valore significa che non si è trovata corrispondenza. In caso
-    di errore o fine del file viene invece restituito \val{EOF}.}
-\end{functions}
-\noindent e come per le analoghe funzioni di scrittura esistono le relative
-\funcm{vscanf}, \funcm{vfscanf} e \funcm{vsscanf} che usano un puntatore ad
-una lista di argomenti.
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int scanf(const char *format, ...)}
+\fdesc{Esegue la scansione di dati dallo \textit{standard input}.}
+\fdecl{int fscanf(FILE *stream, const char *format, ...)}
+\fdesc{Esegue la scansione di dati da uno \textit{stream}. } 
+\fdecl{int sscanf(char *str, const char *format, ...)}
+\fdesc{Esegue la scansione di dati da un buffer.} 
+}
+
+{La funzione ritorna il numero di elementi assegnati in caso di successo e
+  \val{EOF} per un errore o se si raggiunta la fine del file.}
+\end{funcproto}
+
+Le funzioni eseguono una scansione della rispettiva fonte di input cercando
+una corrispondenza di quanto letto con il formato dei dati specificato
+da \param{format}, ed effettua le relative conversioni memorizzando il
+risultato negli argomenti seguenti, il cui numero è variabile e dipende dal
+valore di \param{format}. Come per le analoghe funzioni di scrittura esistono
+le relative \funcm{vscanf}, \funcm{vfscanf} e \funcm{vsscanf} che usano un
+puntatore ad una lista di argomenti. Le funzioni ritornano il numero di
+elementi assegnati. Questi possono essere in numero inferiore a quelli
+specificati, ed anche zero. Quest'ultimo valore significa che non si è trovata
+corrispondenza.
 
 Tutte le funzioni della famiglia delle \func{scanf} vogliono come argomenti i
 puntatori alle variabili che dovranno contenere le conversioni; questo è un
@@ -3169,7 +3985,7 @@ in campi fissi. Uno spazio in \param{format} corrisponde con un numero
 qualunque di caratteri di separazione (che possono essere spazi, tabulatori,
 virgole ecc.), mentre caratteri diversi richiedono una corrispondenza
 esatta. Le direttive di conversione sono analoghe a quelle di \func{printf} e
-si trovano descritte in dettaglio nelle pagine di manuale e nel manuale delle
+si trovano descritte in dettaglio nelle pagine di manuale e nel manuale della
 \acr{glibc}.
 
 Le funzioni eseguono la lettura dall'input, scartano i separatori (e gli
@@ -3190,107 +4006,21 @@ conversione delle stringhe; se invece il formato è più complesso diventa più
 facile utilizzare uno strumento come \cmd{flex}\footnote{il programma
   \cmd{flex}, è una implementazione libera di \cmd{lex} un generatore di
   analizzatori lessicali. Per i dettagli si può fare riferimento al manuale
-  \cite{flex}.} per generare un analizzatore lessicale o il
+  \cite{flex}.} per generare un analizzatore lessicale o 
 \cmd{bison}\footnote{il programma \cmd{bison} è un clone del generatore di
   parser \cmd{yacc}, maggiori dettagli possono essere trovati nel relativo
   manuale \cite{bison}.} per generare un parser.
 
 
-\subsection{Posizionamento su uno \textit{stream}}
-\label{sec:file_fseek}
-
-Come per i file descriptor anche per gli \textit{stream} è possibile spostarsi
-all'interno di un file per effettuare operazioni di lettura o scrittura in un
-punto prestabilito; sempre che l'operazione di riposizionamento sia supportata
-dal file sottostante lo \textit{stream}, quando cioè si ha a che fare con
-quello che viene detto un file ad \textsl{accesso casuale}.\footnote{dato che
-  in un sistema Unix esistono vari tipi di file, come le fifo ed i
-  \index{file!di~dispositivo} file di dispositivo, non è scontato che questo
-  sia sempre vero.}
-
-In GNU/Linux ed in generale in ogni sistema unix-like la posizione nel file è
-espressa da un intero positivo, rappresentato dal tipo \type{off\_t}, il
-problema è che alcune delle funzioni usate per il riposizionamento sugli
-\textit{stream} originano dalle prime versioni di Unix, in cui questo tipo non
-era ancora stato definito, e che in altri sistemi non è detto che la posizione
-su un file venga sempre rappresentata con il numero di caratteri dall'inizio
-(ad esempio in VMS può essere rappresentata come numero di record, più
-l'offset rispetto al record corrente).
-
-Tutto questo comporta la presenza di diverse funzioni che eseguono
-sostanzialmente le stesse operazioni, ma usano argomenti di tipo diverso. Le
-funzioni tradizionali usate per il riposizionamento della posizione in uno
-\textit{stream} sono \funcd{fseek} e \funcd{rewind} i cui prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h} 
-  
-  \funcdecl{int fseek(FILE *stream, long offset, int whence)} Sposta la
-  posizione nello \textit{stream} secondo quanto specificato
-  tramite \param{offset} e \param{whence}.
-
-  \funcdecl{void rewind(FILE *stream)} Riporta la posizione nello
-  \textit{stream} all'inizio del file.
-\end{functions}
-
-L'uso di \func{fseek} è del tutto analogo a quello di \func{lseek} per i file
-descriptor, e gli argomenti, a parte il tipo, hanno lo stesso significato; in
-particolare \param{whence} assume gli stessi valori già visti in
-sez.~\ref{sec:file_lseek}.  La funzione restituisce 0 in caso di successo e -1
-in caso di errore.  La funzione \func{rewind} riporta semplicemente la
-posizione corrente all'inizio dello \textit{stream}, ma non esattamente
-equivalente ad una \code{fseek(stream, 0L, SEEK\_SET)} in quanto vengono
-cancellati anche i flag di errore e fine del file.
-
-Per ottenere la posizione corrente si usa invece la funzione \funcd{ftell}, il
-cui prototipo è:
-\begin{prototype}{stdio.h}{long ftell(FILE *stream)} 
-  Legge la posizione attuale nello \textit{stream} \param{stream}.
-  
-  \bodydesc{La funzione restituisce la posizione corrente, o -1 in caso
-    di fallimento, che può esser dovuto sia al fatto che il file non
-    supporta il riposizionamento che al fatto che la posizione non può
-    essere espressa con un \ctyp{long int}}
-\end{prototype}
-\noindent la funzione restituisce la posizione come numero di byte
-dall'inizio dello \textit{stream}. 
-
-Queste funzioni esprimono tutte la posizione nel file come un \ctyp{long int}.
-Dato che (ad esempio quando si usa un filesystem indicizzato a 64 bit) questo
-può non essere possibile lo standard POSIX ha introdotto le nuove funzioni
-\funcd{fgetpos} e \funcd{fsetpos}, che invece usano il nuovo tipo
-\type{fpos\_t}, ed i cui prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h} 
-  
-  \funcdecl{int fsetpos(FILE *stream, fpos\_t *pos)} Imposta la posizione
-  corrente nello \textit{stream} \param{stream} al valore specificato
-  da \param{pos}.
-  
-  \funcdecl{int fgetpos(FILE *stream, fpos\_t *pos)} Legge la posizione
-  corrente nello \textit{stream} \param{stream} e la scrive in \param{pos}.
-  
-  \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di
-    errore.}
-\end{functions}
-
-In Linux, a partire dalle glibc 2.1, sono presenti anche le due funzioni
-\func{fseeko} e \func{ftello}, che sono assolutamente identiche alle
-precedenti \func{fseek} e \func{ftell} ma hanno argomenti di tipo
-\type{off\_t} anziché di tipo \ctyp{long int}. Dato che \ctyp{long} è nella
-gran parte dei casi un intero a 32 bit, questo diventa un problema quando la
-posizione sul file viene espressa con un valore a 64 bit come accade nei
-sistemi più moderni.
-
-% TODO: mettere prototipi espliciti fseeko e ftello o menzione?
-
 
 \section{Funzioni avanzate}
 \label{sec:file_stream_adv_func}
 
 In questa sezione esamineremo alcune funzioni avanzate che permettono di
-eseguire operazioni particolari sugli \textit{stream}, come leggerne gli
-attributi, controllarne le modalità di bufferizzazione, gestire direttamente i
-lock impliciti per la programmazione \itindex{thread} \textit{multi-thread}.
+eseguire operazioni di basso livello nella gestione degli \textit{stream},
+come leggerne gli attributi, controllarne le modalità di bufferizzazione,
+gestire in maniera esplicita i lock impliciti presenti ad uso della
+programmazione \textit{multi-thread}.
 
 
 \subsection{Le funzioni di controllo}
@@ -3299,55 +4029,72 @@ lock impliciti per la programmazione \itindex{thread} \textit{multi-thread}.
 Al contrario di quanto avviene con i file descriptor, le librerie standard del
 C non prevedono nessuna funzione come la \func{fcntl} per il controllo degli
 attributi dei file. Però, dato che ogni \textit{stream} si appoggia ad un file
-descriptor, si può usare la funzione \funcd{fileno} per ottenere quest'ultimo,
-il prototipo della funzione è:
-\begin{prototype}{stdio.h}{int fileno(FILE *stream)}
-  Legge il file descriptor sottostante lo \textit{stream} \param{stream}.
-  
-  \bodydesc{Restituisce il numero del file descriptor in caso di successo, e
-    -1 qualora \param{stream} non sia valido, nel qual caso imposta
-    \var{errno} a \errval{EBADF}.}
-\end{prototype}
-\noindent ed in questo modo diventa possibile usare direttamente \func{fcntl}.
-
-Questo permette di accedere agli attributi del file descriptor sottostante lo
-\textit{stream}, ma non ci dà nessuna informazione riguardo alle proprietà
-dello \textit{stream} medesimo.  Le \acr{glibc} però supportano alcune
-estensioni derivate da Solaris, che permettono di ottenere informazioni utili.
+descriptor, si può usare la funzione \funcd{fileno} per ottenere il valore di
+quest'ultimo; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int fileno(FILE *stream)}
+\fdesc{Legge il file descriptor sottostante lo \textit{stream}.} 
+}
+
+{La funzione ritorna il numero del file descriptor in caso di successo e $-1$
+  per un errore, nel qual caso \var{errno} assumerà il valore \errval{EBADF}
+  se \param{stream} non è valido.}
+\end{funcproto}
+
+In questo modo diventa possibile usare direttamente \func{fcntl} sul file
+descriptor sottostante, ma anche se questo permette di accedere agli attributi
+del file descriptor sottostante lo \textit{stream}, non ci dà nessuna
+informazione riguardo alle proprietà dello \textit{stream} medesimo.  La
+\acr{glibc} però supporta alcune estensioni derivate da Solaris, che
+permettono di ottenere informazioni utili relative allo \textit{stream}.
 
 Ad esempio in certi casi può essere necessario sapere se un certo
 \textit{stream} è accessibile in lettura o scrittura. In genere questa
-informazione non è disponibile, e si deve ricordare come il file è stato
-aperto. La cosa può essere complessa se le operazioni vengono effettuate in
-una subroutine, che a questo punto necessiterà di informazioni aggiuntive
-rispetto al semplice puntatore allo \textit{stream}; questo può essere evitato
+informazione non è disponibile, e ci si deve ricordare come è stato aperto il
+file. La cosa può essere complessa se le operazioni vengono effettuate in una
+subroutine, che a questo punto necessiterà di informazioni aggiuntive rispetto
+al semplice puntatore allo \textit{stream}. Questo problema può essere risolto
 con le due funzioni \funcd{\_\_freadable} e \funcd{\_\_fwritable} i cui
 prototipi sono:
-\begin{functions}
-  \headdecl{stdio\_ext.h}
-  \funcdecl{int \_\_freadable(FILE *stream)}
-  Restituisce un valore diverso da zero se \param{stream} consente la lettura.
-
-  \funcdecl{int \_\_fwritable(FILE *stream)}  
-  Restituisce un valore diverso da zero se \param{stream} consente la
-  scrittura.
-\end{functions}
+
+\begin{funcproto}{
+\fhead{stdio\_ext.h}
+\fdecl{int \_\_freadable(FILE *stream)}
+\fdesc{Controlla se uno \textit{stream} consente la lettura.} 
+\fdecl{int \_\_fwritable(FILE *stream)}
+\fdesc{Controlla se uno \textit{stream} consente la scrittura.} 
+}
+
+{Le funzioni ritornano un valore diverso da $0$ se l'operazione richiesta è
+  consentita, non sono previste condizioni di errore.}  
+\end{funcproto}
+
 \noindent che permettono di ottenere questa informazione.
 
 La conoscenza dell'ultima operazione effettuata su uno \textit{stream} aperto
 è utile in quanto permette di trarre conclusioni sullo stato del buffer e del
 suo contenuto. Altre due funzioni, \funcd{\_\_freading} e \funcd{\_\_fwriting}
 servono a tale scopo, il loro prototipo è:
-\begin{functions}
-  \headdecl{stdio\_ext.h}
-  \funcdecl{int \_\_freading(FILE *stream)}
-  Restituisce un valore diverso da zero se \param{stream} è aperto in sola
-  lettura o se l'ultima operazione è stata di lettura.
 
-  \funcdecl{int \_\_fwriting(FILE *stream)}  
-  Restituisce un valore diverso da zero se \param{stream} è aperto in sola
-  scrittura o se l'ultima operazione è stata di scrittura.
-\end{functions}
+\begin{funcproto}{
+\fhead{stdio\_ext.h}
+\fdecl{int \_\_freading(FILE *stream)}
+\fdesc{Controlla l'ultima operazione di lettura.}
+\fdecl{int \_\_fwriting(FILE *stream)}
+\fdesc{Controlla l'ultima operazione di scrittura.}
+}
+
+{Le funzioni ritornano un valore diverso da $0$ se l'operazione richiesta è
+  consentita, non sono previste condizioni di errore.}
+\end{funcproto}
+
+La funzione \func{\_\_freading} restituisce un valore diverso da zero
+se \param{stream} è aperto in sola lettura o se l'ultima operazione è stata di
+lettura mentre \func{\_\_fwriting} restituisce un valore diverso da zero
+se \param{stream} è aperto in sola scrittura o se l'ultima operazione è stata
+di scrittura.
 
 Le due funzioni permettono di determinare di che tipo è stata l'ultima
 operazione eseguita su uno \textit{stream} aperto in lettura/scrittura;
@@ -3369,43 +4116,25 @@ vengono allocati automaticamente.
 Però una volta che si sia aperto lo \textit{stream} (ma prima di aver compiuto
 operazioni su di esso) è possibile intervenire sulle modalità di buffering; la
 funzione che permette di controllare la bufferizzazione è \funcd{setvbuf}, il
-suo prototipo è:
-\begin{prototype}{stdio.h}{int setvbuf(FILE *stream, char *buf, int mode, 
-    size\_t size)}
-  
-  Imposta la bufferizzazione dello \textit{stream} \param{stream} nella
-  modalità indicata da \param{mode}, usando \param{buf} come buffer di
-  lunghezza
-  \param{size}.
-  
-  \bodydesc{Restituisce zero in caso di successo, ed un valore qualunque in
-    caso di errore, nel qual caso \var{errno} viene impostata opportunamente.}
-\end{prototype}
-
-La funzione permette di controllare tutti gli aspetti della bufferizzazione;
-l'utente può specificare un buffer da usare al posto di quello allocato dal
-sistema passandone alla funzione l'indirizzo in \param{buf} e la dimensione in
-\param{size}. 
+cui prototipo è:
 
-Ovviamente se si usa un buffer specificato dall'utente questo deve essere
-stato allocato e rimanere disponibile per tutto il tempo in cui si opera sullo
-\textit{stream}. In genere conviene allocarlo con \func{malloc} e disallocarlo
-dopo la chiusura del file; ma fintanto che il file è usato all'interno di una
-funzione, può anche essere usata una \index{variabili!automatiche} variabile
-automatica. In \headfile{stdio.h} è definita la macro \const{BUFSIZ}, che
-indica le dimensioni generiche del buffer di uno \textit{stream}; queste
-vengono usate dalla funzione \func{setbuf}.  Non è detto però che tale
-dimensione corrisponda sempre al valore ottimale (che può variare a seconda
-del dispositivo).
-
-Dato che la procedura di allocazione manuale è macchinosa, comporta dei rischi
-(come delle scritture accidentali sul buffer) e non assicura la scelta delle
-dimensioni ottimali, è sempre meglio lasciare allocare il buffer alle funzioni
-di libreria, che sono in grado di farlo in maniera ottimale e trasparente
-all'utente (in quanto la deallocazione avviene automaticamente). Inoltre
-siccome alcune implementazioni usano parte del buffer per mantenere delle
-informazioni di controllo, non è detto che le dimensioni dello stesso
-coincidano con quelle su cui viene effettuato l'I/O.
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int setvbuf(FILE *stream, char *buf, int mode, size\_t size)}
+\fdesc{Imposta la bufferizzazione dello \textit{stream}.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e un altro valore qualunque per
+  un errore, nel qual caso \var{errno} assumerà un valore appropriato.}  
+\end{funcproto}
+
+La funzione imposta la bufferizzazione dello \textit{stream} \param{stream}
+nella modalità indicata da \param{mode} con uno dei valori di
+tab.~\ref{tab:file_stream_buf_mode}, usando \param{buf} come buffer di
+lunghezza \param{size} e permette di controllare tutti gli aspetti della
+bufferizzazione. L'utente può specificare un buffer da usare al posto di
+quello allocato dal sistema passandone alla funzione l'indirizzo
+in \param{buf} e la dimensione in \param{size}.
 
 \begin{table}[htb]
   \centering
@@ -3415,9 +4144,9 @@ coincidano con quelle su cui viene effettuato l'I/O.
       \textbf{Valore} & \textbf{Modalità} \\
       \hline
       \hline
-      \const{\_IONBF} & \textit{unbuffered}\\
-      \const{\_IOLBF} & \textit{line buffered}\\
-      \const{\_IOFBF} & \textit{fully buffered}\\
+      \constd{\_IONBF} & \textit{unbuffered}\\
+      \constd{\_IOLBF} & \textit{line buffered}\\
+      \constd{\_IOFBF} & \textit{fully buffered}\\
       \hline
     \end{tabular}
     \caption{Valori dell'argomento \param{mode} di \func{setvbuf} 
@@ -3425,6 +4154,26 @@ coincidano con quelle su cui viene effettuato l'I/O.
   \label{tab:file_stream_buf_mode}
 \end{table}
 
+Ovviamente se si usa un buffer specificato dall'utente questo deve essere
+stato allocato e rimanere disponibile per tutto il tempo in cui si opera sullo
+\textit{stream}. In genere conviene allocarlo con \func{malloc} e disallocarlo
+dopo la chiusura del file; ma fintanto che il file è usato all'interno di una
+funzione, può anche essere usata una variabile automatica. In
+\headfile{stdio.h} è definita la costante \constd{BUFSIZ}, che indica le
+dimensioni generiche del buffer di uno \textit{stream}, queste vengono usate
+dalla funzione \func{setbuf}.  Non è detto però che tale dimensione
+corrisponda sempre al valore ottimale (che può variare a seconda del
+dispositivo).
+
+Dato che la procedura di allocazione manuale è macchinosa, comporta dei
+rischi, come delle scritture accidentali sul buffer, e non assicura la scelta
+delle dimensioni ottimali, è sempre meglio lasciare allocare il buffer alle
+funzioni di libreria, che sono in grado di farlo in maniera ottimale e
+trasparente all'utente (in quanto la deallocazione avviene
+automaticamente). Inoltre siccome alcune implementazioni usano parte del
+buffer per mantenere delle informazioni di controllo, non è detto che le
+dimensioni dello stesso coincidano con quelle su cui viene effettuato l'I/O.
+
 Per evitare che \func{setvbuf} imposti il buffer basta passare un valore
 \val{NULL} per \param{buf} e la funzione ignorerà l'argomento \param{size}
 usando il buffer allocato automaticamente dal sistema.  Si potrà comunque
@@ -3433,56 +4182,70 @@ opportuni valori elencati in tab.~\ref{tab:file_stream_buf_mode}. Qualora si
 specifichi la modalità non bufferizzata i valori di \param{buf} e \param{size}
 vengono sempre ignorati.
 
-Oltre a \func{setvbuf} le \acr{glibc} definiscono altre tre funzioni per la
+Oltre a \func{setvbuf} la \acr{glibc} definisce altre tre funzioni per la
 gestione della bufferizzazione di uno \textit{stream}: \funcd{setbuf},
-\funcd{setbuffer} e \funcd{setlinebuf}; i loro prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h} 
-  
-  \funcdecl{void setbuf(FILE *stream, char *buf)} Disabilita la
-  bufferizzazione se \param{buf} è \val{NULL}, altrimenti usa \param{buf}
-  come buffer di dimensione \const{BUFSIZ} in modalità \textit{fully buffered}.
-  
-  \funcdecl{void setbuffer(FILE *stream, char *buf, size\_t size)} Disabilita
-  la bufferizzazione se \param{buf} è \val{NULL}, altrimenti usa \param{buf}
-  come buffer di dimensione \param{size} in modalità \textit{fully buffered}.
-  
-  \funcdecl{void setlinebuf(FILE *stream)} Pone lo \textit{stream} in modalità
-  \textit{line buffered}.
-\end{functions}
-\noindent tutte queste funzioni sono realizzate con opportune chiamate a
-\func{setvbuf} e sono definite solo per compatibilità con le vecchie librerie
-BSD. Infine le \acr{glibc} provvedono le funzioni non standard\footnote{anche
-  queste funzioni sono originarie di Solaris.} \funcd{\_\_flbf} e
-\funcd{\_\_fbufsize} che permettono di leggere le proprietà di bufferizzazione
-di uno \textit{stream}; i cui prototipi sono:
-\begin{functions}
-  \headdecl{stdio\_ext.h} 
-  
-  \funcdecl{int \_\_flbf(FILE *stream)} Restituisce un valore diverso da zero
-  se \param{stream} è in modalità \textit{line buffered}.
-  
-  \funcdecl{size\_t \_\_fbufsize(FILE *stream)} Restituisce le dimensioni del
-  buffer di \param{stream}.
-\end{functions}
+\funcd{setbuffer} e \funcd{setlinebuf}, i rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{void setbuf(FILE *stream, char *buf)}
+\fdecl{void setbuffer(FILE *stream, char *buf, size\_t size)}
+\fdesc{Impostano il buffer per uno \textit{stream}.} 
+\fdecl{void setlinebuf(FILE *stream)}
+\fdesc{Porta uno \textit{stream} in modalità \textit{line buffered}.}
+}
+
+{Le funzioni non ritornano niente e non hanno condizioni di errore.}  
+\end{funcproto}
+
+
+La funzione \func{setbuf} disabilita la bufferizzazione se \param{buf} è
+\val{NULL}, altrimenti usa \param{buf} come buffer di dimensione
+\const{BUFSIZ} in modalità \textit{fully buffered}, mentre \func{setbuffer}
+disabilita la bufferizzazione se \param{buf} è \val{NULL}, altrimenti
+usa \param{buf} come buffer di dimensione \param{size} in modalità
+\textit{fully buffered}.  Tutte queste funzioni sono realizzate con opportune
+chiamate a \func{setvbuf} e sono definite solo per compatibilità con le
+vecchie librerie BSD, pertanto non è il caso di usarle se non per la
+portabilità su vecchi sistemi.
+
+Infine la \acr{glibc} provvede le funzioni non standard, anche queste
+originarie di Solaris, \funcd{\_\_flbf} e \funcd{\_\_fbufsize} che permettono
+di leggere le proprietà di bufferizzazione di uno \textit{stream}; i cui
+prototipi sono:
+
+\begin{funcproto}{
+\fhead{stdio\_ext.h}
+\fdecl{size\_t \_\_fbufsize(FILE *stream)}
+\fdesc{Restituisce le dimensioni del buffer di uno \textit{stream}.}
+\fdecl{int \_\_flbf(FILE *stream)}
+\fdesc{Controlla la modalità di bufferizzazione di uno \textit{stream}.}
+}
+
+{Le funzioni ritornano rispettivamente la dimensione del buffer o un valore
+  non nullo se lo \textit{stream} è in modalità \textit{line-buffered}, non
+  sono previste condizioni di errore.}
+\end{funcproto}
 
 Come già accennato, indipendentemente dalla modalità di bufferizzazione
 scelta, si può forzare lo scarico dei dati sul file con la funzione
-\funcd{fflush}, il suo prototipo è:
-\begin{prototype}{stdio.h}{int fflush(FILE *stream)}
-  
-  Forza la scrittura di tutti i dati bufferizzati dello
-  \textit{stream} \param{stream}.
-  
-  \bodydesc{Restituisce zero in caso di successo, ed \val{EOF} in caso di
-    errore, impostando \var{errno} a \errval{EBADF} se \param{stream} non è
-    aperto o non è aperto in scrittura, o ad uno degli errori di
-    \func{write}.}
-\end{prototype}
-\noindent anche di questa funzione esiste una analoga
-\func{fflush\_unlocked}\footnote{accessibile definendo \macro{\_BSD\_SOURCE} o
-  \macro{\_SVID\_SOURCE} o \macro{\_GNU\_SOURCE}.} che non effettua il blocco
-dello stream.
+\funcd{fflush}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int fflush(FILE *stream)}
+\fdesc{Forza la scrittura dei dati bufferizzati di uno \textit{stream}.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e \val{EOF} per un errore, nel
+  qual caso \var{errno} assumerà il valore \errval{EBADF} se \param{stream}
+  non è aperto o non è aperto in scrittura, o ad uno degli errori di
+  \func{write}.}
+\end{funcproto}
+
+\noindent anche di questa funzione esiste una analoga \func{fflush\_unlocked}
+(accessibile definendo una fra \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE} o
+\macro{\_GNU\_SOURCE}) che non effettua il blocco dello \textit{stream}.
 
 % TODO aggiungere prototipo \func{fflush\_unlocked}?
 
@@ -3490,12 +4253,18 @@ Se \param{stream} è \val{NULL} lo scarico dei dati è forzato per tutti gli
 \textit{stream} aperti. Esistono però circostanze, ad esempio quando si vuole
 essere sicuri che sia stato eseguito tutto l'output su terminale, in cui serve
 poter effettuare lo scarico dei dati solo per gli \textit{stream} in modalità
-line buffered; per questo motivo le \acr{glibc} supportano una estensione di
-Solaris, la funzione \funcd{\_flushlbf}, il cui prototipo è:
-\begin{prototype}{stdio-ext.h}{void \_flushlbf(void)}
-  Forza la scrittura di tutti i dati bufferizzati degli \textit{stream} in
-  modalità line buffered.
-\end{prototype}
+\textit{line buffered}. Per fare questo la \acr{glibc} supporta una
+estensione di Solaris, la funzione \funcd{\_flushlbf}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio-ext.h}
+\fdecl{void \_flushlbf(void)}
+\fdesc{Forza la scrittura dei dati bufferizzati degli \textit{stream} in
+  modalità \textit{line buffered}.} 
+}
+
+{La funzione non ritorna nulla e non presenta condizioni di errore.}  
+\end{funcproto}
 
 Si ricordi comunque che lo scarico dei dati dai buffer effettuato da queste
 funzioni non comporta la scrittura di questi su disco; se si vuole che il
@@ -3504,13 +4273,15 @@ usare \func{sync} o \func{fsync} (si veda~sez.~\ref{sec:file_sync}).
 
 Infine esistono anche circostanze in cui si vuole scartare tutto l'output
 pendente; per questo si può usare \funcd{fpurge}, il cui prototipo è:
-\begin{prototype}{stdio.h}{int fpurge(FILE *stream)}
-  Cancella i buffer di input e di output dello \textit{stream} \param{stream}.
-  
-  \bodydesc{Restituisce zero in caso di successo, ed \val{EOF} in caso di
-    errore.}
-\end{prototype}
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int fpurge(FILE *stream)}
+\fdesc{Cancella i buffer di uno \textit{stream}.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e \val{EOF} per un errore.}  
+\end{funcproto}
 
 La funzione scarta tutti i dati non ancora scritti (se il file è aperto in
 scrittura), e tutto l'input non ancora letto (se è aperto in lettura),
@@ -3520,7 +4291,6 @@ compresi gli eventuali caratteri rimandati indietro con \func{ungetc}.
 \subsection{Gli \textit{stream} e i \textit{thread}}
 \label{sec:file_stream_thread}
 
-\itindbeg{thread}
 
 Gli \textit{stream} possono essere usati in applicazioni \textit{multi-thread}
 allo stesso modo in cui sono usati nelle applicazioni normali, ma si deve
@@ -3532,82 +4302,115 @@ pesantemente dalle richieste necessarie per garantirne l'uso con i
 Lo standard POSIX richiede che le operazioni sui file siano atomiche rispetto
 ai \textit{thread}, per questo le operazioni sui buffer effettuate dalle
 funzioni di libreria durante la lettura e la scrittura di uno \textit{stream}
-devono essere opportunamente protette (in quanto il sistema assicura
-l'atomicità solo per le \textit{system call}). Questo viene fatto associando
-ad ogni \textit{stream} un opportuno blocco che deve essere implicitamente
+devono essere opportunamente protettein quanto il sistema assicura
+l'atomicità solo per le \textit{system call}. Questo viene fatto associando ad
+ogni \textit{stream} un opportuno blocco che deve essere implicitamente
 acquisito prima dell'esecuzione di qualunque operazione.
 
 Ci sono comunque situazioni in cui questo non basta, come quando un
 \textit{thread} necessita di compiere più di una operazione sullo
-\textit{stream} atomicamente, per questo motivo le librerie provvedono anche
-delle funzioni \funcd{flockfile}, \funcd{ftrylockfile} e \funcd{funlockfile},
-che permettono la gestione esplicita dei blocchi sugli \textit{stream}; esse
-sono disponibili definendo \macro{\_POSIX\_THREAD\_SAFE\_FUNCTIONS} ed i loro
-prototipi sono:
-\begin{functions}
-  \headdecl{stdio.h}
-  
-  \funcdecl{void flockfile(FILE *stream)} Esegue l'acquisizione del lock dello
-  \textit{stream} \param{stream}, bloccandosi se il lock non è disponibile.
-  
-  \funcdecl{int ftrylockfile(FILE *stream)} Tenta l'acquisizione del lock
-  dello \textit{stream} \param{stream}, senza bloccarsi se il lock non è
-  disponibile.  Ritorna zero in caso di acquisizione del lock, diverso da zero
-  altrimenti.
-  
-  \funcdecl{void funlockfile(FILE *stream)} Rilascia il lock dello
-  \textit{stream} \param{stream}.
-\end{functions}
-\noindent con queste funzioni diventa possibile acquisire un blocco ed
-eseguire tutte le operazioni volute, per poi rilasciarlo. 
-
-Ma, vista la complessità delle strutture di dati coinvolte, le operazioni di
-blocco non sono del tutto indolori, e quando il locking dello \textit{stream}
-non è necessario (come in tutti i programmi che non usano i \textit{thread}),
-tutta la procedura può comportare dei costi pesanti in termini di
-prestazioni. Per questo motivo abbiamo visto come alle usuali funzioni di I/O
-non formattato siano associate delle versioni \code{\_unlocked} (alcune
-previste dallo stesso standard POSIX, altre aggiunte come estensioni dalle
-\acr{glibc}) che possono essere usate quando il locking non serve\footnote{in
-  certi casi dette funzioni possono essere usate, visto che sono molto più
-  efficienti, anche in caso di necessità di locking, una volta che questo sia
-  stato acquisito manualmente.}  con prestazioni molto più elevate, dato che
-spesso queste versioni (come accade per \func{getc} e \func{putc}) sono
-realizzate come macro.
+\textit{stream} atomicamente. Per questo motivo le librerie provvedono anche
+le funzioni \funcd{flockfile} e \funcd{funlockfile} che permettono la gestione
+esplicita dei blocchi sugli \textit{stream}. Esse sono disponibili definendo
+\macrod{\_POSIX\_THREAD\_SAFE\_FUNCTIONS} ed i loro prototipi sono:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{void flockfile(FILE *stream)}
+\fdesc{Acquisisce il lock su uno \textit{stream}.} 
+\fdecl{void funlockfile(FILE *stream)}
+\fdesc{Rilascia  il lock su uno \textit{stream}.} 
+}
+{Le funzioni non ritornano nulla e non sono previste condizioni di errore.}  
+\end{funcproto}
+
+La funzione \func{flockfile} esegue l'acquisizione del lock dello
+\textit{stream} \param{stream}, bloccandosi se questo risulta non è
+disponibile, mentre \func{funlockfile} rilascia un lock che si è
+precedentemente acquisito.
+
+Una terza funzione, che serve a provare ad acquisire un lock senza bloccarsi
+qualora non sia possibile, è \funcd{ftrylockfile}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int ftrylockfile(FILE *stream)}
+\fdesc{Tenta l'acquisizione del lock di uno \textit{stream}.} 
+}
+
+{La funzione ritorna $0$ in caso di acquisizione del lock ed un altro valore
+  qualunque altrimenti, non sono previste condizioni di errore.}
+\end{funcproto}
+
+Con queste funzioni diventa possibile acquisire un blocco ed eseguire tutte le
+operazioni volute, per poi rilasciarlo. Ma, vista la complessità delle
+strutture di dati coinvolte, le operazioni di blocco non sono del tutto
+indolori, e quando il locking dello \textit{stream} non è necessario (come in
+tutti i programmi che non usano i \textit{thread}), tutta la procedura può
+comportare dei costi pesanti in termini di prestazioni. 
+
+Per questo motivo abbiamo visto come alle usuali funzioni di I/O non
+formattato siano associate delle versioni \code{\_unlocked} (alcune previste
+dallo stesso standard POSIX, altre aggiunte come estensioni dalla \acr{glibc})
+che possono essere usate quando il locking non serve\footnote{in certi casi
+  dette funzioni possono essere usate, visto che sono molto più efficienti,
+  anche in caso di necessità di locking, una volta che questo sia stato
+  acquisito manualmente.}  con prestazioni molto più elevate, dato che spesso
+queste versioni (come accade per \func{getc} e \func{putc}) sono realizzate
+come macro.
 
 La sostituzione di tutte le funzioni di I/O con le relative versioni
 \code{\_unlocked} in un programma che non usa i \textit{thread} è però un
-lavoro abbastanza noioso; per questo motivo le \acr{glibc} forniscono al
-programmatore pigro un'altra via\footnote{anche questa mutuata da estensioni
-  introdotte in Solaris.} da poter utilizzare per disabilitare in blocco il
+lavoro abbastanza noioso. Per questo motivo la \acr{glibc} fornisce al
+programmatore pigro un'altra viaanche questa mutuata da estensioni
+introdotte in Solaris, da poter utilizzare per disabilitare in blocco il
 locking degli \textit{stream}: l'uso della funzione \funcd{\_\_fsetlocking},
 il cui prototipo è:
-\begin{prototype}{stdio\_ext.h}{int \_\_fsetlocking (FILE *stream, int type)}
-  Specifica o richiede a seconda del valore di \param{type} la modalità in cui
-  le operazioni di I/O su \param{stream} vengono effettuate rispetto
-  all'acquisizione implicita del blocco sullo \textit{stream}.
-
-  \bodydesc{Restituisce lo stato di locking interno dello \textit{stream} con
-    uno dei valori \const{FSETLOCKING\_INTERNAL} o
-    \const{FSETLOCKING\_BYCALLER}.}
-\end{prototype}
-
-La funzione imposta o legge lo stato della modalità di operazione di uno
-\textit{stream} nei confronti del locking a seconda del valore specificato
-con \param{type}, che può essere uno dei seguenti:
-\begin{basedescript}{\desclabelwidth{4.0cm}}
-\item[\const{FSETLOCKING\_INTERNAL}] Lo \textit{stream} userà da ora in poi il
-  blocco implicito predefinito.
-\item[\const{FSETLOCKING\_BYCALLER}] Al ritorno della funzione sarà l'utente a
-  dover gestire da solo il locking dello \textit{stream}.
-\item[\const{FSETLOCKING\_QUERY}] Restituisce lo stato corrente della modalità
-  di blocco dello \textit{stream}.
-\end{basedescript}
 
-% TODO trattare \func{clearerr\_unlocked} 
+\begin{funcproto}{
+\fhead{stdio\_ext.h}
+\fdecl{int \_\_fsetlocking(FILE *stream, int type)}
+\fdesc{Specifica se abilitare il locking su uno \textit{stream}.}
+}
 
+{La funzione ritorna stato di locking interno dello \textit{stream}, non sono
+  previste condizioni di errore.}  
+\end{funcproto}
 
-\itindend{thread}
+La funzione imposta o legge lo stato della modalità in cui le operazioni di
+I/O su \param{stream} vengono effettuate rispetto all'acquisizione implicita
+del locking a seconda del valore specificato con \param{type}, che può
+assumere uno dei valori indicati in tab.~\ref{tab:file_fsetlocking_type}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+    \begin{tabular}[c]{|l|p{8cm}|}
+      \hline
+      \textbf{Valore} & \textbf{Significato} \\
+      \hline
+      \hline
+      \constd{FSETLOCKING\_INTERNAL}& Lo \textit{stream} userà da ora in poi il
+                                      blocco implicito predefinito.\\
+      \constd{FSETLOCKING\_BYCALLER}& Al ritorno della funzione sarà l'utente a
+                                      dover gestire da solo il locking dello
+                                      \textit{stream}.\\
+      \constd{FSETLOCKING\_QUERY}   & Restituisce lo stato corrente della
+                                      modalità di blocco dello
+                                      \textit{stream}.\\
+      \hline
+    \end{tabular}
+    \caption{Valori dell'argomento \param{type} di \func{\_\_fsetlocking} 
+      per l'impostazione delle modalità di bufferizzazione.}
+  \label{tab:file_fsetlocking_type}
+\end{table}
+
+La funzione, se usata con \const{FSETLOCKING\_QUERY}, non modifica la modalità
+di operazione ma restituisce lo stato di locking interno dello \textit{stream}
+con uno dei valori \const{FSETLOCKING\_INTERNAL} o
+\const{FSETLOCKING\_BYCALLER}.
+
+% TODO trattare \func{clearerr\_unlocked} 
 
 
 
@@ -3621,12 +4424,12 @@ con \param{type}, che può essere uno dei seguenti:
 % LocalWords:  nell'header stdin shell stdout stderr error freopen flush line
 % LocalWords:  unbuffered buffered newline fully SVr fopen fdopen POSIX const
 % LocalWords:  char path int fildes NULL errno malloc fcntl fclose fflush tab
-% LocalWords:  dup fifo socket append EXCL ccs IRUSR IWUSR IRGRP IWGRP
+% LocalWords:  dup fifo socket append EXCL ccs IRUSR IWUSR IRGRP IWGRP inode fd
 % LocalWords:  IROTH IWOTH umask fseek fsetpos rewind SEEK CUR EOF EBADF close
-% LocalWords:  sync fcloseall void stdlib of feof ferror clearerr ws
+% LocalWords:  sync fcloseall void stdlib of feof ferror clearerr ws VFS table
 % LocalWords:  unlocked fread fwrite size ptr nmemb nelem gcc padding point str
-% LocalWords:  lock thread fgetc getc getchar dell'overhead unsigned ap
-% LocalWords:  getwc fgetwc getwchar wint wchar WEOF putc fputc putchar 
+% LocalWords:  lock thread fgetc getc getchar dell'overhead unsigned ap process
+% LocalWords:  getwc fgetwc getwchar wint wchar WEOF putc fputc putchar  struct
 % LocalWords:  SVID getw putw parsing peeking ahead ungetc gets fgets string Di
 % LocalWords:  overflow Aleph stack fputs puts fgetws fputws getline ssize leak
 % LocalWords:  realloc value result argument memory getdelim delim printf short
@@ -3637,14 +4440,38 @@ con \param{type}, che può essere uno dei seguenti:
 % LocalWords:  lseek ftell fgetpos fpos fseeko ftello fileno Solaris freadable
 % LocalWords:  fwritable ext freading fwriting buffering setvbuf BUFSIZ setbuf
 % LocalWords:  IONBF IOLBF IOFBF setbuffer setlinebuf flbf fbufsize flushlbf hh
-% LocalWords:  fsync fpurge flockfile ftrylockfile funlockfile 
-% LocalWords:  locking fsetlocking type  Virtual operation
-% LocalWords:  modification hole functions FSETSIG
-
-
-
+% LocalWords:  fsync fpurge flockfile ftrylockfile funlockfile  files fig flags
+% LocalWords:  locking fsetlocking type virtual operation dentry unistd sys AT
+% LocalWords:  modification hole functions pathname EEXIST CREAT EINTR attack
+% LocalWords:  EISDIR EFBIG EOVERFLOW ELOOP NOFOLLOW ENODEV ENOENT ENOTDIR fork
+% LocalWords:  EMFILE ENAMETOOLONG ENFILE ENOMEM ENOSPC EROFS exec access RDWR
+% LocalWords:  RDONLY ioctl AND ACCMODE creation Denial Service DoS opendir NFS
+% LocalWords:  SOURCE LARGEFILE BITS NOCTTY TRUNC SHLOCK shared EXLOCK race SGI
+% LocalWords:  exclusive condition change ASYNC SIGIO CLOEXEC DIRECT NDELAY EIO
+% LocalWords:  DSYNC FASYNC IRIX FreeBSD EINVAL client RSYNC creat filedes INCR
+% LocalWords:  behind shutdown ESPIPE XTND truncate fallocate count EAGAIN log
+% LocalWords:  timerfd Specification pwrite pread define XOPEN EPIPE SIGPIPE at
+% LocalWords:  caching cache update bdflush fdatasync fstat oldfd newfd DUPFD
+% LocalWords:  openat mkdirat mkdir proc ATFILE dirfd FDCWD utimes lutimes uid
+% LocalWords:  utimensat faccessat fchmodat chmod fchownat chown lchown fstatat
+% LocalWords:  lstat linkat mknodat mknod readlinkat readlink renameat rename
+% LocalWords:  symlinkat symlink unlinkat unlink rmdir mkfifoat mkfifo owner is
+% LocalWords:  gid group FOLLOW REMOVEDIR cmd arg flock SETFD GETFD GETFL SETFL
+% LocalWords:  GETLK SETLK SETLKW GETOWN PID Signal SIGURG SETOWN GETSIG SETSIG
+% LocalWords:  sigaction SIGINFO siginfo SETLEASE lease GETLEASE NOTIFY request
+% LocalWords:  everything framebuffer ENOTTY argp CDROM lsattr chattr magic TID
+% LocalWords:  number FIOCLEX FIONCLEX FIOASYNC FIONBIO FIOSETOWN FIOGETOWN pid
+% LocalWords:  FIONREAD epoll FIOQSIZE side effects SAFE BYCALLER QUERY EACCES
+% LocalWords:  EBUSY OpenBSD syncfs futimes timespec only init ESRCH kill NTPL
+% LocalWords:  ENXIO  NONBLOCK WRONLY EPERM NOATIME ETXTBSY EWOULDBLOCK PGRP SZ
+% LocalWords:  EFAULT capabilities GETPIPE SETPIPE RESOURCE dell'I all' NFSv
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
+
+% LocalWords:  nell' du vm Documentation Urlich Drepper futimesat times
+%  LocalWords:  futimens fs Tread all'I ll TMPFILE EDQUOT extN Minix UDF XFS
+%  LocalWords:  shmem Btrfs ubifs tmpfile fchmod fchown fsetxattr fchdir PF
+%  LocalWords:  fstatfs sull'