Varie su lseek
[gapil.git] / fileio.tex
index be7fa7666fcddae3ad5a6072cff69a304f9a793e..601d98bd10f99df4e7c8bad8536a9878420764ae 100644 (file)
@@ -29,7 +29,7 @@ ultime le caratteristiche più avanzate.
 \label{sec:file_unix_interface}
 
 
-Come visto in sez.~\ref{sec:file_vfs_work} il kernel mette a disposione
+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
@@ -92,7 +92,7 @@ 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 il flag di stato \itindex{file~status~flag} del file nel campo
+\item i flag di stato \itindex{file~status~flag} del file nel campo
   \var{f\_flags}.
 \item la posizione corrente nel file, il cosiddetto \textit{offset}, nel campo
   \var{f\_pos}.
@@ -132,37 +132,37 @@ essenziali come:
 \end{itemize*}
 
 In questa infrastruttura un \textit{file descriptor} non è altro che l'intero
-positivo che indicizza quest'ultima tabella, grazie al quale si può recuperare
-il puntatore alla struttura \kstruct{file} nella \itindex{file~table}
-\textit{file table} corrispondente al file che è stato aperto dal processo e a
-cui era stato assegnato questo indice. Ma una volta indicato col \textit{file
-  descriptor} qual'è la struttura \kstruct{file} nella \textit{file table}
-corrispondente al file voluto, il kernel potrà usare le funzioni messe
-disposizione dal VFS per eseguire sul file tutte le operazioni necessarie.
+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.
 
 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.
 
-In tutti i sistemi unix-like esiste poi una convenzione generale per cui ogni
-processo viene lanciato dalla shell con almeno tre file aperti. Questi, per
-quanto appena detto, avranno come \itindex{file~descriptor} \textit{file
-  descriptor} i valori 0, 1 e 2.  Benché questa sia soltanto una convenzione,
-essa è seguita dalla gran parte delle applicazioni, e non aderirvi potrebbe
-portare a gravi problemi di interoperabilità.
-
-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
+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.  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 provvede, al posto dei valori numerici, tre costanti
-simboliche, definite in tab.~\ref{tab:file_std_files}.
+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
+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
+provvede, al posto dei valori numerici, tre costanti simboliche, definite in
+tab.~\ref{tab:file_std_files}.
 
 \begin{table}[htb]
   \centering
@@ -180,8 +180,7 @@ simboliche, definite in tab.~\ref{tab:file_std_files}.
       error}\\
     \hline
   \end{tabular}
-  \caption{Costanti definite in \headfile{unistd.h} per i file standard aperti 
-    alla creazione di ogni processo.}
+  \caption{Costanti definite in \headfile{unistd.h} per i file standard.}
   \label{tab:file_std_files}
 \end{table}
 
@@ -210,7 +209,7 @@ relativo \itindex{inode} \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
 dimensioni del vettore di puntatori con cui era realizzata la tabella dei file
-descriptor dentro \kstruct{files\_struct}; questo limite intrinseco nei kernel
+descriptor dentro \kstruct{files\_struct}. Questo limite intrinseco nei kernel
 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}).
@@ -273,8 +272,8 @@ corrispondente,\footnote{è \func{open} che alloca \kstruct{file}, la inserisce
   \errval{EROFS}, nel loro significato generico.}
 \end{funcproto}
 
-La funzione apre il file indicato da \param{pathname} nella modalità indicata da
-\param{flags}. Essa può essere invocata in due modi diversi, specificando
+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
@@ -283,14 +282,14 @@ delle costanti descritte in tab.~\ref{tab:file_bit_perm}. Questi permessi sono
 comunque filtrati dal valore della \itindex{umask} \textit{umask} (vedi
 sez.~\ref{sec:file_perm_management}) del processo.
 
-La funzione restituisce sempre il primo file descriptor libero, e questa
-caratteristica permette di prevedere qual è il valore del file descriptor che
-si otterrà al ritorno di \func{open}, e viene spesso usata dalle applicazioni
-per sostituire i file corrispondenti ai file standard visti in
+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} (avrà cioè il file descriptor 0).
+  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
@@ -302,14 +301,14 @@ 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.
 
-Il comportamento della funzione e le diverse modalità con cui può essere
-aperto il file vengono controllati dall'argomento \param{flags} il cui valore
+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 (o \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 \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}).
 
 Ciascun flag viene identificato da una apposita costante, ed il valore
 di \param{flags} deve essere specificato come OR aritmetico di queste
@@ -339,84 +338,97 @@ costanti di tab.~\ref{tab:open_access_mode_flag}.
 \end{table}
 
 A differenza di tutti gli altri flag che vedremo in seguito, in questo caso
-non si ha a che fare con singoli bit separati, ma con un numero composto da
-due bit, e che può essere ottenuto dal valore dei \itindex{file~status~flag}
-\textit{file status flags} con un AND aritmetico con la maschera binaria
-\const{O\_ACCMODE}. Questo significa ad esempio che la combinazione
-\code{\const{O\_RDONLY}|\const{O\_WRONLY}} non è affatto equivalente a
-\const{O\_WRONLY}, e non deve essere usata.\footnote{in realtà su Linux, dove
-  i valori per le tre costanti di tab.~\ref{tab:open_access_mode_flag} sono
-  rispettivamente $0$, $1$ e $2$, il valore $3$ viene usato con un significato
-  speciale ed assolutamente fuori standard, disponibile solo per i file di
-  dispositivo e solo per alcuni driver, in cui si richiede la verifica della
-  capacità di accesso in lettura e scrittura ma viene restituito in file
-  descriptor che non può essere letto o scritto ma solo usato con una
-  \func{ioctl} (vedi sez.~\ref{sec:file_ioctl}).}
-
-Una modalità di accesso al file deve sempre essere specificata quando si apre
-un file, il valore indicato in \param{flags} viene salvato nei
+non si ha a che fare con singoli bit separati dell'argomento \param{flags}, ma
+con un numero composto da due bit. Questo significa ad esempio che la
+combinazione \code{\const{O\_RDONLY}|\const{O\_WRONLY}} non è affatto
+equivalente a \const{O\_RDWR}, e non deve essere usata.\footnote{in realtà
+  su Linux, dove i valori per le tre costanti di
+  tab.~\ref{tab:open_access_mode_flag} sono rispettivamente $0$, $1$ e $2$, il
+  valore $3$ viene usato con un significato speciale, ed assolutamente fuori
+  standard, disponibile solo per i file di dispositivo e solo per alcuni
+  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}).}
+
+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}, ma non può essere modificato. Nella \acr{glibc} sono
-definite \const{O\_READ} come sinonimo di \const{O\_RDONLY}, \const{O\_WRITE}
-come sinonimo di \const{O\_WRONLY} ed una \const{O\_EXEC} che non esiste su
-Linux per l'apertura per l'esecuzione.\footnote{si tratta di definizioni
-  completamente fuori standard, che suppongono anche l'uso di bit distinti, ed
-  non è il caso di utilizzarle anche quando coincidenti con quelle di Linux.}
+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 secondo gruppo di flag è quello delle \textsl{modalità di
   apertura},\footnote{la pagina di manuale di \func{open} parla di
-  \textit{file creation flags}, ma alcuni di questi non hanno nulla a che fare
-  con la creazione dei file, mentre il manuale dalla \acr{glibc} parla di più
-  correttamente di \textit{open-time flags}, dato che si tratta di flag il cui
-  significato ha senso solo al momento dell'apertura del file.} che permettono
-di specificare alcune delle caratteristiche del comportamento di \func{open}
-quando viene eseguita. Hanno effetto solo al momento della chiamata della
-funzione e non sono memorizzati \itindex{file~status~flag} \textit{file status
-  flags} né possono essere riletti.
+  \textit{file creation flags}, ma alcuni di questi flag non hanno nulla a che
+  fare con la creazione dei file, mentre il manuale dalla \acr{glibc} parla di
+  più correttamente di \textit{open-time flags}, dato che si tratta di flag il
+  cui significato ha senso solo al momento dell'apertura del file.} che
+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}).
 
 \begin{table}[htb]
   \centering
   \footnotesize
-    \begin{tabular}[c]{|l|p{8 cm}|}
+    \begin{tabular}[c]{|l|p{10 cm}|}
       \hline
       \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}. Con
-                            questa opzione l'argomento \param{mode} deve
-                            essere specificato.\\ 
+                            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 (dal kernel 2.1.126). Questo
-                            flag è specifico di Linux ed è stato introdotto
-                            per evitare dei \itindex{Denial~of~Service~(DoS)} 
-                            \textit{DoS}\footnotemark\\ quando \func{opendir}
+                            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
-                            utilizzato al di fuori dell'implementazione di
-                            \func{opendir}.\\
-      \const{O\_EXCL}     & Se usato in congiunzione con \const{O\_CREAT} fa
-                            richiede che il file indicato da \param{pathname}
-                            non esista (altrimenti causa un errore di
-                            \errcode{EEXIST}).\\  
-      \const{O\_LARGEFILE}& Nel caso di sistemi a 32 bit che supportano file
-                            di grandi dimensioni consente di aprire file le
-                            cui dimensioni non possono essere rappresentate da
-                            numeri a 31 bit.\\
+                            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
                             la chiamata fallisce. Questa è un'estensione BSD
-                            aggiunta in Linux dal kernel 2.1.126. Nelle
-                            versioni precedenti i collegamenti simbolici sono 
-                            sempre seguiti, e questa opzione è ignorata.\\
+                            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 di \func{open} non è specificato.\\ 
+                            comportamento non è specificato.\\ 
       \hline
     \end{tabular}
     \caption{Le costanti che identificano le \textit{modalità di apertura} di
@@ -429,127 +441,192 @@ funzione e non sono memorizzati \itindex{file~status~flag} \textit{file status
   causando una qualche forma di carico eccessivo per il sistema, che resta
   bloccato nelle risposte all'attacco.}
 
+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
+  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}).}
+
+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
+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]
+  \centering
+  \footnotesize
+    \begin{tabular}[c]{|l|p{10 cm}|}
+      \hline
+      \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 è
+                           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
+                           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}).\\
+      \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
+                           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
+                           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
+                           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
+                           scrittura di dati si bloccherà fino alla conferma
+                           dell'arrivo degli stessi e della parte di metadati
+                           ad essi relativa sull'hardware sottostante (in
+                           questo significato solo dal kernel 2.6.33).\\
+      \hline
+    \end{tabular}
+    \caption{Le costanti che identificano le \textit{modalità di operazione} di
+      un file.} 
+  \label{tab:open_operation_flag}
+\end{table}
 
-
-
-\footnote{la pagina di
-      manuale di \func{open} segnala che questa opzione è difettosa su NFS, e
-      che i programmi che la usano per stabilire un \index{file!di lock}
-      \textsl{file di lock} possono incorrere in una \itindex{race~condition}
-      \textit{race condition}.  Si consiglia come alternativa di usare un file
-      con un nome univoco e la funzione \func{link} per verificarne
-      l'esistenza (vedi sez.~\ref{sec:ipc_file_lock}).}
-
-
-\const{O\_SHLOCK} Apre il file con uno shared lock (vedi
-    sez.~\ref{sec:file_locking}). Specifica di BSD, assente in Linux.
-
-\const{O\_EXLOCK} Apre il file con un lock esclusivo (vedi
-    sez.~\ref{sec:file_locking}). Specifica di BSD, assente in Linux.
-
-
-Il terzo gruppo è quello dei flag delle \textsl{modalità di operazione} che
-permettono di specificare alcune caratteristiche del comportamento delle
-future operazioni sul file (come \func{read} o \func{write}). Anch'essi fan
-parte del \textit{file status flag}. Il loro valore è impostato alla chiamata
-di \func{open}, ma possono essere riletti e modificati (insieme alle
-caratteristiche operative che controllano) con una \func{fcntl}.
-
-
-\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}}
-
-  \item[\const{O\_APPEND}] Il file viene aperto in \itindex{append~mode}
-    \textit{append mode}. Prima di ciascuna scrittura la posizione corrente
-    viene sempre impostata alla fine del file. Con NFS si può avere una
-    corruzione del file se più di un processo scrive allo stesso
-    tempo.\footnote{il problema è che NFS non supporta la scrittura in
-      \itindex{append~mode} \textit{append}, ed il kernel deve simularla, ma
-      questo comporta la possibilità di una \itindex{race~condition}
-      \textit{race condition}, vedi sez.~\ref{sec:file_atomic}.}
-
-  \item[\const{O\_ASYNC}] Apre il file per l'I/O in modalità asincrona (vedi
-    sez.~\ref{sec:file_asyncronous_io}). Quando è impostato viene generato il
-    segnale \signal{SIGIO} tutte le volte che sono disponibili dati in input
-    sul file.
-
-  \item[\const{O\_CLOEXEC}] Attiva la modalità di \itindex{close-on-exec}
-    \textit{close-on-exec} (vedi sez.~\ref{sec:proc_exec}). Introdotto con il
-    kernel 2.6.23, per evitare una \itindex{race~condition} \textit{race
-      condition} che si può verificare con i \itindex{thread} \textit{thread},
-    fra l'apertura del file e l'impostazione della suddetta modalità con
-    \func{fcntl} (vedi sez.~\ref{sec:file_fcntl}).
-
-  \item[\const{O\_DIRECT}] Esegue l'I/O direttamente dai buffer in user space
-    in maniera sincrona, in modo da scavalcare i meccanismi di caching del
-    kernel. In genere questo peggiora le prestazioni tranne quando le
-    applicazioni ottimizzano il proprio caching.\footnote{l'opzione è stata
-      introdotta dalla SGI in IRIX, e serve sostanzialmente a permettere ad
-      alcuni programmi (in genere database) la gestione diretta della
-      bufferizzazione dell'I/O in quanto essi sono in grado di ottimizzarla al
-      meglio per le loro prestazioni; l'opzione è presente anche in FreeBSD,
-      senza limiti di allineamento dei buffer. In Linux è stata introdotta con
-      il kernel 2.4.10, le versioni precedenti la ignorano.}  Per i kernel
-    della serie 2.4 si deve garantire che i buffer in user space siano
-    allineati alle dimensioni dei blocchi del filesystem; per il kernel 2.6
-    basta che siano allineati a multipli di 512 byte.
-
-  \item[\const{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.
-
-  \item[\const{O\_NONBLOCK}] Il file viene aperto in modalità non bloccante
-    per le operazioni di I/O (che tratteremo in
-    sez.~\ref{sec:file_noblocking}): questo significa il fallimento di
-    \func{read} in assenza di dati da leggere e quello di \func{write} in caso
-    di impossibilità di scrivere immediatamente. Questa modalità ha senso solo
-    per le fifo e per alcuni file di dispositivo.
-
-  \item[\const{O\_NONBLOCK}] Apre il file in modalità non bloccante, e
-    comporta che \func{open} ritorni immediatamente anche quando dovrebbe
-    bloccarsi (l'opzione ha senso solo per le fifo, vedi
-    sez.~\ref{sec:ipc_named_pipe}).
-
- \item[\const{O\_NDELAY}] In Linux è sinonimo di
-    \const{O\_NONBLOCK}.\footnote{l'opzione 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 zero da parte di \func{read} ha
-      il significato di una \textit{end-of-file}.}
-
-  \item[\const{O\_SYNC}] Apre il file per l'input/output sincrono: ogni
-    \func{write} bloccherà fino al completamento della scrittura di tutti i
-    dati sull'hardware sottostante.
-
-  \item[\const{O\_FSYNC}] Sinonimo di \const{O\_SYNC}, usato da BSD.
-
-  \item[\const{O\_DSYNC}] Variante di I/O sincrono definita da POSIX; presente
-    dal kernel 2.1.130 come sinonimo di \const{O\_SYNC}.
-
-  \item[\const{O\_RSYNC}] Variante analoga alla precedente, trattata allo
-    stesso modo.
-
-\end{basedescript}
-
-
-%TODO trattare 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/
-
-
-In tab.~\ref{tab:file_open_flags} sono riportate, ordinate e divise fra loro
-secondo le tre modalità appena elencate, le costanti mnemoniche associate a
-ciascuno di questi bit. Dette costanti possono essere combinate fra loro con
-un OR aritmetico per costruire il valore (in forma di maschera binaria)
-dell'argomento \param{flags} da passare alla \func{open}. I due flag
-\const{O\_NOFOLLOW} e \const{O\_DIRECTORY} sono estensioni specifiche di
-Linux, e deve essere definita la macro \macro{\_GNU\_SOURCE} per poterli
-usare.
+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 è
+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}.
+
+Lo scopo di \const{O\_DIRECT} è consentire un completo controllo sulla
+bufferizzazione dei propri dati per quelle applicazioni (in genere database)
+che hanno esigenze specifiche che non vengono soddisfatte nella maniera più
+efficiente dalla politica generica utilizzata dal kernel. In genere l'uso di
+questo flag peggiora le prestazioni tranne quando le applicazioni sono in
+grado di ottimizzare la propria bufferizzazione in maniera adeguata. Se lo si
+usa si deve avere cura di non mescolare questo tipo di accesso con quello
+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 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
+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.
+
+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
+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}.
+
+% 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/ 
 
 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 system call apposita,
-\funcd{creat}, il cui prototipo è:
+questo motivo per creare un nuovo file c'era una \textit{system call}
+apposita, \funcd{creat}, nel caso di Linux questo non è più necessario ma la
+funzione è definita ugualmente; il suo prototipo è:
 
 \begin{funcproto}{
 \fhead{fcntl.h}
@@ -558,11 +635,10 @@ questo motivo per creare un nuovo file c'era una system call apposita,
 }
 
 {La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
-  caso \var{errno} assumerà gli stessi valori che si otterebbero con
+  caso \var{errno} assumerà gli stessi valori che si otterrebbero con
   \func{open}.}
 \end{funcproto}
 
-
 La funzione crea un nuovo file vuoto, con i permessi specificati
 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
@@ -572,38 +648,46 @@ vecchi programmi.
 \subsection{La funzione \func{close}}
 \label{sec:file_close}
 
-La funzione \funcd{close} permette di chiudere un file, in questo modo il file
-descriptor ritorna disponibile; il suo prototipo è:
-\begin{prototype}{unistd.h}{int close(int fd)}
-  Chiude il descrittore \param{fd}. 
-  
-  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
-    errore, con \var{errno} che assume i valori:
+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à
+disponibile; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int close(int fd)}
+\fdesc{Chiude 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{EBADF}]  \param{fd} non è un descrittore valido.
     \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
   \end{errlist}
-  ed inoltre \errval{EIO}.}
-\end{prototype}
+  ed inoltre \errval{EIO} nel suo significato generico.}
+\end{funcproto}
 
-La chiusura di un file rilascia ogni blocco (il \textit{file locking}
-\itindex{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) 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.
-
-Si ricordi che quando un processo termina anche tutti i suoi file descriptor
-vengono chiusi, molti programmi sfruttano questa caratteristica e non usano
-esplicitamente \func{close}. In genere comunque chiudere un file senza
-controllarne lo stato di uscita è errore; infatti molti filesystem
-implementano la tecnica del \textit{write-behind}, per cui una \func{write}
-può avere successo anche se i dati non sono stati scritti, un eventuale errore
-di I/O allora può sfuggire, ma verrà riportato alla chiusura del file: per
-questo motivo non effettuare il controllo può portare ad una perdita di dati
-inavvertita.\footnote{in Linux questo comportamento è stato osservato con NFS
-  e le quote su disco.}
+La funzione chiude il file descriptor \param{fd}, la chiusura rilascia ogni
+blocco (il \textit{file locking} \itindex{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.
+
+Si ricordi che quando un processo termina tutti i suoi file descriptor vengono
+automaticamente chiusi, molti programmi sfruttano questa caratteristica e non
+usano esplicitamente \func{close}. In genere comunque chiudere un file senza
+controllare lo stato di uscita di \func{close} un è errore; molti filesystem
+infatti implementano la tecnica del cosiddetto \textit{write-behind}, per cui
+una \func{write} può avere successo anche se i dati non sono stati
+effettivamente scritti su disco. In questo caso un eventuale errore di I/O
+avvenuto in un secondo tempo potrebbe sfuggire, mentre verrebbe riportato alla
+chiusura esplicita del file. Per questo motivo non effettuare il controllo può
+portare ad una perdita di dati inavvertita.\footnote{in Linux questo
+  comportamento è stato osservato con NFS e le quote su disco.}
 
 In ogni caso una \func{close} andata a buon fine non garantisce che i dati
 siano stati effettivamente scritti su disco, perché il kernel può decidere di
@@ -620,57 +704,83 @@ di ripetere tre volte il comando prima di eseguire lo shutdown).
 
 Come già accennato in sez.~\ref{sec:file_fd} a ciascun file aperto è associata
 una \textsl{posizione corrente nel file} (il cosiddetto \textit{file offset},
-mantenuto nel campo \var{f\_pos} di \kstruct{file}) espressa da un numero intero
-positivo come 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}
-\const{O\_APPEND}) questa posizione viene impostata a zero all'apertura del
-file. È possibile impostarla ad un valore qualsiasi con la funzione
-\funcd{lseek}, il cui prototipo è:
-\begin{functions}
-  \headdecl{sys/types.h}
-  \headdecl{unistd.h}
-  \funcdecl{off\_t lseek(int fd, off\_t offset, int whence)}
-  Imposta la posizione attuale nel file. 
-  
-  \bodydesc{La funzione ritorna il valore della posizione corrente in caso di
-    successo e $-1$ in caso di errore nel qual caso \var{errno} assumerà uno
-    dei valori:
+mantenuto nel campo \var{f\_pos} di \kstruct{file}) espressa da un numero
+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 è:
+
+\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..} 
+}
+
+{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}.
   \end{errlist}
-  ed inoltre \errval{EBADF}.}
-\end{functions}
+  ed inoltre \errval{EBADF} nel suo significato generico.}
+\end{funcproto}
 
-La nuova posizione è impostata usando il valore specificato da \param{offset},
-sommato al riferimento dato da \param{whence}; quest'ultimo può assumere i
-seguenti valori\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}.}:
-\begin{basedescript}{\desclabelwidth{2.0cm}}
-\item[\const{SEEK\_SET}] si fa riferimento all'inizio del file: il valore
-  (sempre positivo) di \param{offset} indica direttamente la nuova posizione
-  corrente.
-\item[\const{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.
-\item[\const{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.
-\end{basedescript}
+La funzione imposta la nuova posizione sul file usando il valore specificato
+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}.} 
 
-% TODO, trattare, SEEK_HOLE e SEEK_DATA, inclusi nel kernel 3.1, vedi
-% http://lwn.net/Articles/439623/ 
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{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:
+                        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
+                        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
+                        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
+                        \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}.\\ 
+    \hline
+  \end{tabular}
+  \caption{Possibili valori per l'argomento \param{whence} di \func{lseek}.}
+  \label{tab:lseek_whence_values}
+\end{table}
 
 
+% 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 valore
-\var{f\_pos} in \param{file}, vedi fig.~\ref{fig:file_proc_file}).  Dato che
+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)}.
@@ -696,16 +806,16 @@ un errore ma restituiscono un valore indefinito.
 
 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; ed in tal caso alla successiva scrittura il file sarà esteso a
-partire da detta posizione. In questo caso si ha quella che viene chiamata la
-creazione di un \index{file!\textit{hole}} \textsl{buco} nel file, accade cioè
-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 corrisponda ad una allocazione effettiva di
-spazio su disco, che sarebbe inutile dato che quella zona è effettivamente
-vuota.
-
-Questa è una delle caratteristiche spcifiche della gestione dei file di un
+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.
+
+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
@@ -729,7 +839,7 @@ Questo avviene proprio perché in un sistema unix-like la dimensione di un file
 effettivamente allocato, e viene registrata sull'\textit{inode} come le altre
 proprietà del file. La dimensione viene aggiornata automaticamente quando si
 estende un file scrivendoci, e viene riportata dal campo \var{st\_size} di una
-struttura \struct{stat} quando si effettua chiamata ad una delle funzioni
+struttura \struct{stat} quando si effettua la chiamata ad una delle funzioni
 \texttt{*stat} viste in sez.~\ref{sec:file_stat}.
 
 Questo comporta che in generale, fintanto che lo si è scritto sequenzialmente,
@@ -752,6 +862,21 @@ inutilizzato.
 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 è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{ssize\_t read(int fd, void * buf, size\_t count)}
+\fdesc{Legge i dati da 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}
+  \end{errlist}
+  ed inoltre 
+ 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
@@ -817,15 +942,16 @@ dati in ingresso: la funzione allora ritorna immediatamente con un errore
   \errcode{EAGAIN}.} che indica soltanto che non essendoci al momento dati
 disponibili occorre provare a ripetere la lettura in un secondo tempo.
 
-La funzione \func{read} è una delle 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 \acr{glibc}, compresa
-  l'emulazione per i vecchi kernel che non hanno la 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 è:
+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
+  \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)}
 
@@ -1044,14 +1170,14 @@ 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 system call in successione non è un'operazione
-atomica; il problema è stato risolto introducendo la modalità
+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 system call (la \func{write})
-che non essendo interrompibile da un altro processo costituisce un'operazione
-atomica.
+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
@@ -1065,8 +1191,8 @@ 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 system call (per i dettagli sull'uso di questa caratteristica
-si veda sez.~\ref{sec:ipc_file_lock}).
+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}}
@@ -1265,11 +1391,11 @@ 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 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
+  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
@@ -1970,7 +2096,7 @@ usare la funzione \func{freopen}.
 
 La bufferizzazione è una delle caratteristiche principali dell'interfaccia
 degli \textit{stream}; lo scopo è quello di ridurre al minimo il numero di
-system call (\func{read} o \func{write}) eseguite nelle operazioni di
+\textit{system call} (\func{read} o \func{write}) eseguite nelle operazioni di
 input/output. Questa funzionalità è assicurata automaticamente dalla libreria,
 ma costituisce anche uno degli aspetti più comunemente fraintesi, in
 particolare per quello che riguarda l'aspetto della scrittura dei dati sul
@@ -2254,9 +2380,9 @@ intero (di tipo \ctyp{int}) \val{EOF}\footnote{la costante deve essere
   valori diversi.}  definito anch'esso nell'header \headfile{stdlib.h}.
 
 Dato che le funzioni dell'interfaccia degli \textit{stream} sono funzioni di
-libreria che si appoggiano a delle system call, esse non impostano
+libreria che si appoggiano a delle \textit{system call}, esse non impostano
 direttamente la variabile \var{errno}, che mantiene il valore impostato dalla
-system call che ha riportato l'errore.
+\textit{system call} 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
@@ -3407,9 +3533,9 @@ 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 system call). Questo viene fatto associando ad ogni
-\textit{stream} un opportuno blocco che deve essere implicitamente acquisito
-prima dell'esecuzione di qualunque operazione.
+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
@@ -3495,12 +3621,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 STRING IRUSR IWUSR IRGRP IWGRP
+% LocalWords:  dup fifo socket append EXCL ccs IRUSR IWUSR IRGRP IWGRP
 % LocalWords:  IROTH IWOTH umask fseek fsetpos rewind SEEK CUR EOF EBADF close
-% LocalWords:  sync fcloseall SOURCE void stdlib of feof ferror clearerr l'I ws
+% LocalWords:  sync fcloseall void stdlib of feof ferror clearerr ws
 % LocalWords:  unlocked fread fwrite size ptr nmemb nelem gcc padding point str
-% LocalWords:  lock thread fgetc getc getchar dell'overhead altresì unsigned ap
-% LocalWords:  getwc fgetwc getwchar wint wchar WEOF putc fputc putchar dell'I
+% LocalWords:  lock thread fgetc getc getchar dell'overhead unsigned ap
+% LocalWords:  getwc fgetwc getwchar wint wchar WEOF putc fputc putchar 
 % 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
@@ -3511,39 +3637,12 @@ 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 SAFE FUNCTIONS
-% LocalWords:  locking fsetlocking type BYCALLER QUERY ll
-
-
-
-% LocalWords:  descriptor system call cap like kernel sez l'inode inode VFS tab
-% LocalWords:  process table struct files flags pos all'inode dentry fig shell
-% LocalWords:  error POSIX STDIN FILENO STDOUT STDERR unistd read write lseek
-% LocalWords:  close pathname sys fcntl int const char errno EEXIST CREAT EXCL
-% LocalWords:  EISDIR ENOTDIR ENXIO NOBLOCK WRONLY fifo ENODEV ETXTBSY ELOOP of
-% LocalWords:  NOFOLLOW EACCES ENAMETOOLONG ENOENT EROFS EFAULT ENOSPC ENOMEM
-% LocalWords:  EMFILE ENFILE NFS lock race condition Denial Service DoS RDONLY
-% LocalWords:  glibc RDWR NONBLOCK NOCTTY SHLOCK shared BSD EXLOCK TRUNC device
-% LocalWords:  opendir LARGEFILE APPEND append NDELAY ASYNC l'I SIGIO SYNC SVr
-% LocalWords:  DSYNC RSYNC filesystem DIRECT caching SGI IRIX dell'I FreeBSD fd
-% LocalWords:  fork exec umask SOURCE creat filedes EBADF EINTR EIO locking off
-% LocalWords:  behind sync flush shutdown whence ESPIPE socket EINVAL INCR XTND
-% LocalWords:  SEEK CUR EPIPE ssize void buf size count EAGAIN EWOULDBLOCK log
-% LocalWords:  Specification pwrite pread EFBIG SIGPIPE nell'inode dall'inode
-% LocalWords:  CLOEXEC stat fsync cache update l'update bdflush Documentation
-% LocalWords:  fdatasync fstat ext dup oldfd newfd DUPFD cmd long arg flock pid
-% LocalWords:  SETFD GETFD GETFL SETFL GETLK SETLK SETLKW GETOWN group SIGURG
-% LocalWords:  SETOWN GETSIG SETSIG sigaction SIGINFO siginfo SETLEASE lease is
-% LocalWords:  truncate GETLEASE NOTIFY AND ACCMODE ioctl everything argp all'I
-% LocalWords:  framebuffer request ENOTTY CDROM nell'header magic number openat
-% LocalWords:  FIOCLEX FIONCLEX FIOASYNC FIONBIO NOATIME redirezione FIOSETOWN
-% LocalWords:  FIOGETOWN FIONREAD mkdirat thread Solaris mkdir at Urlich proc
-% LocalWords:  Drepper path dirfd faccessat unlinkat access fchmodat chmod Di
-% LocalWords:  fchownat chown fstatat futimesat utimes linkat mknodat mknod uid
-% LocalWords:  readlinkat readlink renameat rename symlinkat symlink unlink gid
-% LocalWords:  mkfifoat mkfifo FDCWD dereferenziazione rmdir REMOVEDIR
-% LocalWords:  epoll lsattr chattr FIOQSIZE ATFILE lutimes utimensat lchown
-% LocalWords:  lstat owner FOLLOW
+% LocalWords:  fsync fpurge flockfile ftrylockfile funlockfile 
+% LocalWords:  locking fsetlocking type  Virtual operation
+% LocalWords:  modification hole functions FSETSIG
+
+
+
 
 %%% Local Variables: 
 %%% mode: latex