Modifiche minime
[gapil.git] / fileunix.tex
index 5734c43c02e99db3ba6261315b1da465ea94597a..258eae0adcc24fa0041238985bd5a4794e44e0a0 100644 (file)
@@ -15,7 +15,8 @@ ANSI C.
 
 In questa sezione faremo una breve introduzione sulla architettura su cui è
 basata dell'interfaccia dei \textit{file descriptor}, che, sia pure con
-differenze di implementazione, è comune ad ogni implementazione di unix.
+differenze nella realizzazione pratica, resta sostanzialmente la stessa in
+ogni implementazione di unix.
 
 
 \subsection{L'architettura dei \textit{file descriptor}}
@@ -79,7 +80,7 @@ strutture di dati sulla quale essa 
   \centering
   \includegraphics[width=14cm]{img/procfile.eps}
   \caption{Schema della architettura dell'accesso ai file attraverso
-  l'interfaccia dei \textit{file descroptor}}
+  l'interfaccia dei \textit{file descriptor}}
   \label{fig:file_proc_file}
 \end{figure}
 Ritorneremo su questo schema più volte, dato che esso è fondamentale per
@@ -166,7 +167,6 @@ system call del kernel.
 La funzione \func{open} è la funzione fondamentale per accedere ai file, ed è
 quella che crea l'associazione fra un pathname ed un file descriptor; il suo
 prototipo è:
-
 \begin{functions}
   \headdecl{sys/types.h}
   \headdecl{sys/stat.h}
@@ -180,7 +180,6 @@ prototipo 
   La funzione ritorna il file descriptor in caso di successo e -1 in caso di
   errore. In questo caso la variabile \var{errno} viene settata ad uno dei
   valori:
-
   \begin{errlist}
   \item \macro{EEXIST} \var{pathname} esiste e si è specificato
     \macro{O\_CREAT} e \macro{O\_EXCL}.  
@@ -213,51 +212,7 @@ di \secref{sec:file_std_descr}: se ad esempio si chiude lo standard input e si
 apre subito dopo un nuovo file questo diventerà il nuovo standard input (avrà
 cioè il file descriptor 0).
 
-Il nuovo file descriptor non è condiviso con nessun altro processo, (torneremo
-sulla condivisione dei file, in genere accessibile dopo una \func{fork}, in
-\secref{sec:file_sharing}). Il nuovo file descriptor è settato di default per
-restare aperto attraverso una \func{exec} (come accennato in
-\secref{sec:proc_exec}) ed l'offset è settato all'inizio del file. 
-
-Il parametro \var{mode} specifica i permessi con cui il file viene
-eventualmente creato; i valori possibili sono gli stessi già visti in
-\secref{sec:file_perm_overview} e possono essere specificati come OR binario
-delle costanti descritte in \tabref{tab:file_bit_perm}. Questi permessi
-filtrati dal valore di \file{umask} (vedi \secref{sec:file_umask}) per il
-processo.
-
-La funzione prevede diverse opzioni, che vengono specificate usando vari bit
-del parametro \var{flags}.  Alcuni di questi bit vanno anche a costituire il
-flag di stato del file (o \textit{file status flag}), che è mantenuto nel
-campo \var{f\_flags} della struttura \var{file} (al solito si veda lo schema
-di \curfig).  Essi sono divisi in tre categorie principali:
-\begin{itemize}
-\item \textsl{i bit delle modalità di accesso}: specificano con quale modalità
-  si accederà al file: i valori possibili sono lettura, scrittura o
-  lettura/scrittura.  Uno di questi bit deve essere sempre specificato quando
-  si apre un file.  Vengono settati alla chiamata da \func{open}, e possono
-  essere riletti con una \func{fcntl} (fanno parte del \textit{file status
-    flag}), ma non modificati.
-\item \textsl{i bit delle modalità di apertura}: 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 nè possono essere riletti.
-\item \textsl{i bit delle modalità di operazione}: permettono di specificare
-  alcune caratteristiche del comportamento delle future operazioni sul file
-  (come la \func{read} o la \func{write}). Anch'essi fanno parte del
-  \textit{file status flag}. Il loro valore è settato alla chiamata di
-  \func{open}, ma possono essere riletti e modificati (insieme alle
-  caratteristiche operative che controllano) con una \func{fcntl}.
-\end{itemize}
-
-In \ntab\ si 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 di loro con un OR
-aritmetico per costruire il valore (in forma di maschera binaria) del
-parametro \var{flags} da passare alla \func{open} per specificarne il
-comportamento.
-
-\begin{table}[!htbp]
+\begin{table}[!htb]
   \centering
   \footnotesize
   \begin{tabular}[c]{|l|p{12cm}|}
@@ -265,51 +220,51 @@ comportamento.
     \textbf{Flag} & \textbf{Descrizione} \\
     \hline
     \hline % modailtà di accesso al file
-    \macro{O\_RDONLY} & apre il file in sola lettura\\
-    \macro{O\_WRONLY} & apre il file in sola scrittura\\
-    \macro{O\_RDWR} & apre il file lettura/scrittura\\
+    \macro{O\_RDONLY} & apre il file in sola lettura\\
+    \macro{O\_WRONLY} & apre il file in sola scrittura\\
+    \macro{O\_RDWR} & apre il file lettura/scrittura\\
     \hline % modalita di apertura del file
     \hline
     \macro{O\_CREAT} & se il file non esiste verrà creato, con le regole di
     titolarità del file viste in \secref{sec:file_ownership}. Il parametro
     \var{mode} deve essere specificato. \\
     \macro{O\_EXCL} & usato in congiunzione con \macro{O\_CREAT} fa sì che
-    l'esistenza del file diventi un errore\footnote{la man page di \func{open}
-    segnala che questa opzione è difettosa su NFS, e che i programmi che la
-    usano per stabilire un file di lock possono incorrere in una race
-    condition.  Si consiglia come alternativa di usare un file con un nome
-    univoco e la funzione \func{link} per verificarne l'esistenza.} che fa
-    fallire \func{open} con \macro{EEXIST}.\\
+    l'esistenza del file diventi un errore\protect\footnote{la man page di 
+      \func{open} segnala che questa opzione è difettosa su NFS, e che i 
+      programmi che la usano per stabilire un file di lock possono incorrere 
+      in una race condition.  Si consiglia come alternativa di usare un file 
+      con un nome univoco e la funzione \func{link} per verificarne 
+      l'esistenza.} che fa fallire \func{open} con \macro{EEXIST}. \\
     \macro{O\_NONBLOCK} & apre il file in modalità non bloccante. Questo
     valore specifica anche una modalità di operazione (vedi sotto), e 
     comporta che \func{open} ritorni immediatamente (torneremo su
-    questo in \secref{sec:file_noblocking}).  \\
+    questo in \secref{sec:file_noblocking}). \\
     \macro{O\_NOCTTY} & se \var{pathname} si riferisce ad un device di
     terminale, questo non diventerà il terminale di controllo, anche se il
-    processo non ne ha ancora uno (si veda \secref{sec:sess_xxx}).\\
+    processo non ne ha ancora uno (si veda \secref{sec:sess_xxx}). \\
     \macro{O\_SHLOCK} & opzione di BSD, acquisisce uno shared lock (vedi
-    \secref{sec:file_locking}) sul file. Non è disponibile in Linux.\\
+    \secref{sec:file_locking}) sul file. Non è disponibile in Linux. \\
     \macro{O\_EXLOCK} & opzione di BSD, acquisisce uno lock esclusivo (vedi
-    \secref{sec:file_locking}) sul file. Non è disponibile in Linux.\\
+    \secref{sec:file_locking}) sul file. Non è disponibile in Linux. \\
     \macro{O\_TRUNC} & se il file esiste ed è un file di dati e la modalità di
     apertura consente la scrittura, allora la sua lunghezza verrà troncata a
     zero. Se il file è un terminale o una fifo il flag verrà ignorato, negli
-    altri casi il comportamento non è specificato.\\
+    altri casi il comportamento non è specificato. \\
     \macro{O\_NOFOLLOW} & se \var{pathname} è un link simbolico la chiamata
     fallisce. Questa è una estensione BSD aggiunta in Linux dal kernel 2.1.126.
     Nelle versioni precedenti i link simbolici sono sempre seguiti, e questa
-    opzione è ignorata.\\
+    opzione è ignorata. \\
     \macro{O\_DIRECTORY} & se \var{pathname} non è una directory la chiamata
     fallisce. Questo flag è specifico di Linux ed è stato introdotto con il
-    kernel 2.1.126 per evitare dei DoS\footnote{Denial of Service, si chiamano
-    così attacchi miranti ad impedire un servizio causando una qualche forma
-    di carico eccessivo per il sistema, che resta bloccato nelle risposte
-    all'attacco} quando \func{opendir} viene chiamata su una fifo o su un
-    device di unità a nastri, non deve essere utilizzato al di fuori
-    dell'implementazione di \func{opendir}. \\
+    kernel 2.1.126 per evitare dei DoS\protect\footnote{Denial of Service, si 
+      chiamano così attacchi miranti ad impedire un servizio causando una 
+      qualche forma di carico eccessivo per il sistema, che resta bloccato 
+      nelle risposte all'attacco} quando \func{opendir} viene chiamata su una 
+    fifo o su un device di unità a nastri, non deve essere utilizzato al di 
+    fuori dell'implementazione di \func{opendir}. \\
     \macro{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.\\
+    essere rappresentate da numeri a 31 bit. \\
     \hline
     \hline  % modalità di operazione col file
     \macro{O\_APPEND} & il file viene aperto in append mode. Prima di ciascuna
@@ -327,13 +282,13 @@ comportamento.
     causava il ritorno da una \func{read} con un valore nullo e non con un
     errore, questo introduce una ambiguità, dato che come vedremo in
     \secref{sec:file_read} il ritorno di zero da parte di \func{read} ha il
-    significato di una end-of-file} è sinonimo di \macro{O\_NONBLOCK}\\
+    significato di una end-of-file} è sinonimo di \macro{O\_NONBLOCK}.\\
     \macro{O\_ASYNC} & apre il file per l'input/output in modalità
     asincrona. Non è supportato in Linux. \\
-    \macro{O\_FSYNC} & \\
     \macro{O\_SYNC} & apre il file per l'input/output sincrono, ogni
     \func{write} bloccherà fino al completamento della scrittura di tutti dati
-    sul sull'hardware sottostante\\
+    sul sull'hardware sottostante.\\
+    \macro{O\_FSYNC} & sinonimo di \macro{O\_SYNC}. \\
     \macro{O\_NOATIME} & blocca l'aggiornamento dei tempi dei di accesso dei
     file (vedi \secref{sec:file_file_times}). In Linux questa opzione non è
     disponibile per il singolo file ma come opzione per il filesystem in fase
@@ -345,11 +300,54 @@ comportamento.
   \label{tab:file_open_flags}
 \end{table}
 
+Il nuovo file descriptor non è condiviso con nessun altro processo, (torneremo
+sulla condivisione dei file, in genere accessibile dopo una \func{fork}, in
+\secref{sec:file_sharing}). Il nuovo file descriptor è settato di default per
+restare aperto attraverso una \func{exec} (come accennato in
+\secref{sec:proc_exec}) ed l'offset è settato all'inizio del file.
+
+Il parametro \var{mode} specifica i permessi con cui il file viene
+eventualmente creato; i valori possibili sono gli stessi già visti in
+\secref{sec:file_perm_overview} e possono essere specificati come OR binario
+delle costanti descritte in \tabref{tab:file_bit_perm}. Questi permessi
+filtrati dal valore di \file{umask} (vedi \secref{sec:file_umask}) per il
+processo.
+
+La funzione prevede diverse opzioni, che vengono specificate usando vari bit
+del parametro \var{flags}.  Alcuni di questi bit vanno anche a costituire il
+flag di stato del file (o \textit{file status flag}), che è mantenuto nel
+campo \var{f\_flags} della struttura \var{file} (al solito si veda lo schema
+di \curfig).  Essi sono divisi in tre categorie principali:
+\begin{itemize}
+\item \textsl{i bit delle modalità di accesso}: specificano con quale modalità
+  si accederà al file: i valori possibili sono lettura, scrittura o
+  lettura/scrittura.  Uno di questi bit deve essere sempre specificato quando
+  si apre un file.  Vengono settati alla chiamata da \func{open}, e possono
+  essere riletti con una \func{fcntl} (fanno parte del \textit{file status
+    flag}), ma non modificati.
+\item \textsl{i bit delle modalità di apertura}: 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 nè possono essere riletti.
+\item \textsl{i bit delle modalità di operazione}: permettono di specificare
+  alcune caratteristiche del comportamento delle future operazioni sul file
+  (come la \func{read} o la \func{write}). Anch'essi fanno parte del
+  \textit{file status flag}. Il loro valore è settato alla chiamata di
+  \func{open}, ma possono essere riletti e modificati (insieme alle
+  caratteristiche operative che controllano) con una \func{fcntl}.
+\end{itemize}
+
+In \tabref{tab:file_open_flags} si 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 di loro
+con un OR aritmetico per costruire il valore (in forma di maschera binaria)
+del parametro \var{flags} da passare alla \func{open} per specificarne il
+comportamento.
+
 Nelle prime versioni di unix i 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, \func{creat}, il cui
 prototipo è:
-
 \begin{prototype}{fcntl.h}
   {int creat(const char *pathname, mode\_t mode)}
   Crea un nuovo file vuoto, con i permessi specificati da \var{mode}. É del
@@ -359,51 +357,390 @@ prototipo 
 adesso questa funzione resta solo per compatibilità con i vecchi programmi.
 
 
+\subsection{La funzione \func{close}}
+\label{sec:file_close}
 
+La funzione \func{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 \var{fd}. 
+  
+  La funzione ritorna 0 in caso di successo e -1 n caso di errore. In questo
+  caso \var{errno} è settata ai valori:
+  \begin{errlist}
+    \item \macro{EBADF}  \var{fd} non è un descrittore valido.
+    \item \macro{EINTR} la funzione è stata interrotta da un segnale.
+  \end{errlist}
+  ed \macro{EIO}.
+\end{prototype}
 
+La chiusura di un file rilascia ogni blocco (il \textit{file locking} è
+trattato in \secref{sec:file_locking}) che il processo poteva avere acquisito
+su di esso; se \var{fd} è ultimo (di eventuali copie) riferimento ad un file
+aperto, tutte le risorse nella 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 sui 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; 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
+ottimizzare l'accesso a disco ritardandone la scrittura. L'uso della funzione
+\func{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).
 
-\subsection{La funzione \func{close}}
-\label{sec:file_close}
 
 \subsection{La funzione \func{lseek}}
 \label{sec:file_lseek}
 
+Come già accennato in \secref{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 \var{file}) espressa da un numero intero
+positivo come numero di bytes 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à \macro{O\_APPEND}) questa
+posizione viene settata a zero all'apertura del file. È possibile settarla ad
+un valore qualsiasi con la funzione \func{lseek}, il cui prototipo è:
+\begin{functions}
+  \headdecl{sys/types.h}
+  \headdecl{unistd.h}
+  \funcdecl{off\_t lseek(int fd, off\_t offset, int whence)}
+  La funzione setta la posizione attuale nel file. 
+
+  La funzione ritorna valore della posizione corrente in caso di successo e -1
+  in caso di errore nel qual caso \var{errno} viene settata ad uno dei valori:
+  \begin{errlist}
+    \item \macro{ESPIPE} \var{fd} è una pipe, un socket o una fifo.
+    \item \macro{EINVAL} \var{whence} non è un valore valido.
+  \end{errlist}
+  e \macro{EBADF}.
+\end{functions}
+
+La nuova posizione è settata usando il valore specificato da \var{offset},
+sommato al riferimento dato da \var{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
+  \macro{L\_SET}, \macro{L\_INCR} e \macro{L\_XTND}}:
+\begin{description}
+\item \macro{SEEK\_SET} si fa riferimento all'inizio del file: il valore di
+  \var{offset} è la nuova posizione.
+\item \macro{SEEK\_CUR} si fa riferimento alla posizione corrente del file:
+  \var{offset} che può essere negativo e positivo.
+\item \macro{SEEK\_END} si fa riferimento alla fine del file: il valore di
+  \var{offset} può essere negativo e positivo.
+\end{description}
+
+Come accennato in \secref{sec:file_file_size} con \func{lseek} è possibile
+settare la posizione corrente anche al di la della fine del file, e alla
+successiva scrittura il file sarà esteso. La chiamata non causa nessuna
+attività di input/output, si limita a modificare la posizione corrente nel
+kernel (cioè \var{f\_pos} in \var{file}, vedi \figref{fig:file_proc_file}).
+
+Dato che la funzione ritorna la nuova posizione, usando il valore zero per
+\func{offset} si può riottenere la posizione corrente nel file chiamando la
+funzione con \func{lseek(fd, 0, SEEK\_CUR}. 
+
+Si tenga presente inoltre che usare \macro{SEEK\_END} non assicura affatto che
+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 settata in precedenza.
+Questa è una potenziale sorgente di \textit{race condition}, e quando si vuole
+essere sicuri di scrivere alla fine del file questo deve essere posto in
+modalità \macro{O\_APPEND}.
+
+Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
+questo caso la funzione ritorna l'errore \macro{EPIPE}. Questo, oltre che per
+i tre casi citati nel prototipo, vale anche per tutti quei dispositivi che non
+supportano questa funzione, come ad esempio per le \acr{tty}\footnote{altri
+  sistemi, usando \macro{SEEK\_SET} in questo caso ritornano il numero di
+  caratteri che vi sono stati scritti}. Lo standard POSIX però non specifica
+niente al proposito. Infine alcuni device, ad esempio \file{/dev/null}, non
+causano un errore ma restituiscono un valore indefinito.
+
+
 \subsection{La funzione \func{read}}
 \label{sec:file_read}
 
+Per leggere da un file precedentemente aperto, si può la funzione \func{read},
+il cui prototipo è:
+\begin{prototype}{unistd.h}{ssize\_t read(int fd, void * buf, size\_t count)}
+  
+  La funzione cerca di leggere \var{count} bytes dal file \var{fd} al buffer
+  \var{buf}.
+  
+  La funzione ritorna il numero di byte letti in caso di successo e -1 in
+  caso di errore, nel qual caso \var{errno} viene settata ad uno dei valori:
+  \begin{errlist}
+  \item \macro{EINTR} la funzione è stata interrotta da un segnale prima di
+    aver potuto leggere quasiasi dato.
+    \item \macro{EAGAIN} la funzione non aveva nessun dato da restituire e si
+      era aperto il file in modalità \macro{O\_NONBLOCK}.
+  \end{errlist}
+  ed inoltre \macro{EBADF}, \macro{EIO}, \macro{EISDIR}, \macro{EBADF},
+  \macro{EINVAL} e \macro{EFAULT} ed eventuali altri errori dipendenti dalla
+  natura dell'oggetto connesso a \var{fd}.
+\end{prototype}
+
+La funzione tenta di leggere \var{count} byte a partire dalla posizione
+corrente nel file; dopo la lettura la posizione è spostata automaticamente in
+avanti del numero di bytes letti. Se \var{count} è zero la funzione
+restituisce zero senza nessun altro risultato.
+
+Si deve sempre tener presente 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 però bisogna sempre tenere
+presente.
+
+La prima e più ovvia di queste ragioni è che si è chiesto di leggere più bytes
+di quanto il file ne contenga. In questo caso il file viene letto fino alla
+sua fine, e la funzione ritorna regolarmente il numero di byte letti
+effettivamente. Se ripetessimo la lettura \func{read} restituirebbe uno zero.
+La condizione raggiungimento della fine del file non è un errore, e viene
+segnalata appunto da un valore di ritorno di \func{read} nullo, ripetere la
+lettura non avrebbe nessun effetto se non quello di 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 la situazione è
+invece normale quando si legge da un terminale, o su una pipe. In tal caso
+infatti, se non ci sono dati in ingresso, la \func{read} si blocca 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.
+
+Lo stesso comportamento avviene caso di lettura dalla rete (cioè su un socket,
+come vedremo in \secref{sec:sock_io_behav}), o per certi dispositivi come le
+unità a nastro che restituiscono un singolo blocco di dati alla volta.
+
+In realtà anche le due condizioni segnalate dagli errori \func{EINTR} e
+\func{EAGAIN} non sono 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 prendere è quella di rieseguire la funzione. Torneremo
+sull'argomento in \secref{sec:signal_xxx}. 
+
+La seconda si verifica quando il file è in modalità non bloccante e non ci
+sono dati in ingresso: la funzione allora ritorna immediatamente con un errore
+\macro{EAGAIN}\footnote{sotto BSD questo per questo errore viene usata la
+  costante \macro{EWOULDBLOCK}, in GNU/Linux questa è sinonima di
+  \macro{EAGAIN}.} indicando che occorrerà provare a ripetere la lettura.
+
+
+Lo standard Unix98\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
+  aggiutno con la versione 2.1} (vedi \secref{sec:intro_opengroup}) prevede la
+definizione di un'altra funzione di lettura, \func{pread}, che diventa
+accessibile con la definizione:
+\begin{verbatim}
+       #define _XOPEN_SOURCE 500
+\end{verbatim}
+il prototipo di questa funzione è:
+\begin{prototype}{unistd.h}
+{ssize\_t pread(int fd, void * buf, size\_t count, off\_t offset)}
+  
+La funzione cerca di leggere \var{count} bytes dal file \var{fd}, a partire
+dalla posizione \var{offset}, nel buffer \var{buf}.
+  
+La funzione ritorna il numero di byte letti in caso di successo e -1 in caso
+di errore, nel qual caso \var{errno} viene settata secondo i valori già visti
+per \func{read} e \func{lseek}.
+\end{prototype}
+
+Questa funzione serve quando si vogliono leggere dati dal file senza
+modificarne la posizione corrente. È equivalente alla esecuzione di una
+\func{read} e una \func{lseek}, ma dato che la posizione sul file può essere
+condivisa fra vari processi (vedi \secref{sec:file_sharing}), essa permette di
+eseguire l'operazione atomicamente. Il valore di \var{offset} fa riferimento
+all'inizio del file.
+
+
 \subsection{La funzione \func{write}}
 \label{sec:file_write}
 
+Per scrivere su un file si usa la funzione \func{write}, il cui prototipo è:
+\begin{prototype}{unistd.h}{ssize\_t write(int fd, void * buf, size\_t count)}
+  
+  La funzione scrive \var{count} bytes dal buffer \var{buf} sul file \var{fd}.
+  
+  La funzione ritorna il numero di byte scritti in caso di successo e -1 in
+  caso di errore, nel qual caso \var{errno} viene settata ad uno dei valori:
+  \begin{errlist}
+  \item \macro{EINVAL} \var{fd} è connesso ad un oggetto che non consente la
+    scrittura.
+  \item \macro{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 \macro{EPIPE} \var{fd} è connesso ad una pipe il cui altro capo è
+    chiuso in lettura; in questo caso viene anche generato il segnale
+    \macro{SIGPIPE}, se questo viene gestito (o bloccato o ignorato) la
+    funzione ritorna questo errore.
+  \item \macro{EINTR} la funzione è stata interrotta da un segnale prima di
+    aver potuto scerivere quasiasi dato.
+  \item \macro{EAGAIN} la funzione non aveva nessun dato da restituire e si
+    era aperto il file in modalità \macro{O\_NONBLOCK}.
+  \end{errlist}
+  ed inoltre \macro{EBADF}, \macro{EIO}, \macro{EISDIR}, \macro{EBADF},
+  \macro{ENOSPC}, \macro{EINVAL} e \macro{EFAULT} ed eventuali altri errori
+  dipendenti dalla natura dell'oggetto connesso a \var{fd}.
+\end{prototype}
+
+Come nel caso di \func{read} la funzione tenta di scrivere \var{count} byte a
+partire dalla posizione corrente nel file e sposta automaticamente la
+posizione in avanti del numero di bytes scritti. Se il file è aperto in
+modalità \macro{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à.
+
+Se \var{count} è zero la funzione restituisce zero senza fare nient'altro. Per
+i file ordinari il numero di bytes scritti è sempre uguale a quello indicato
+da \var{count}, a meno di un errore. Negli altri casi si ha lo stesso
+comportamento di \func{read}.
+
+Anche per \func{write} lo standard Unix98 definisce una analoga 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)}
+  
+La funzione cerca di scrivere sul file \var{fd}, a partire dalla posizione
+\var{offset}, \var{count} bytes dal buffer \var{buf}.
+  
+La funzione ritorna il numero di byte letti in caso di successo e -1 in caso
+di errore, nel qual caso \var{errno} viene settata secondo i valori già visti
+per \func{write} e \func{lseek}.
+\end{prototype}
+
+
 
-\section{Funzioni avanzate}
+\section{Caratteristiche avanzate}
 \label{sec:file_adv_func}
 
+In questa sezione approfondireme alcune delle caratteristiche più sottili
+della gestione file in un sistema unix-like, esaminando in dettaglio il
+comportamento delle funzioni base, inoltre tratteremo alcune funzioni che
+permettono di eseguire operazioni avanzate con i file.
+
+
 \subsection{La condivisione dei files}
 \label{sec:file_sharing}
 
+In \secref{sec:file_fd} abbiamo descritto brevemente l'architettura
+dell'interfaccia coi file da parte di un processo, mostrando in
+\figref{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.
+
+\begin{figure}[htb]
+  \centering
+  \includegraphics[width=14cm]{img/filemultacc.eps}
+  \caption{Schema dell'accesso allo stesso file da parte di due processi 
+    diversi}
+  \label{fig:file_mult_acc}
+\end{figure}
+
+Il primo caso è quello in cui due processi diversi che aprono lo stesso file
+su disco; sulla base di quanto visto in \secref{sec:file_fd} avremo una
+situazione come quella illustrata in \figref{fig:file_mult_acc}: ciascun
+processo avrà una sua voce nella \textit{file table} referenziata da un
+diverso file descriptor nella sua \var{file\_struct}. Entrambe le voci nella
+\textit{file table} faranno però riferimento allo stesso 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 \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} nell'inode.
+\item se un file è in modalità \macro{O\_APPEND} tutte le volte che viene
+  effettuata una scrittura la posizione corrente viene prima settata alla
+  dimensione corrente del file letta dall'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 \var{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 settata leggendo la dimensione corrente dall'inode.
+\end{itemize}
+
+\begin{figure}[htb]
+  \centering
+  \includegraphics[width=14cm]{img/fileshar.eps}
+  \caption{Schema dell'accesso ai file da parte di un processo figlio}
+  \label{fig:file_acc_child}
+\end{figure}
+
+È comunque possibile che due file descriptor di due processi diversi puntino
+alla stessa voce nella \textit{file table}; questo è ad esempio il caso dei
+file aperti che venfono ereditati dal processo figlio all'esecuzione di una
+\func{fork} (si ricordi quanto detto in \secref{sec:proc_fork}). La situazione
+è illustrata in \figref{fig:file_acc_child}; dato che il processo figlio
+riceve una copia dello spazio di indirizzi del padre, riceverà anche una copia
+di \var{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 cosenguenze descritte a suo tempo in
+\secref{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 è la stesso per entrambi).
+
+Si noti inoltre che anche i flag di stato del file (quelli settati dal
+parametro \var{flag} di \func{open}) essendo tenuti nella voce della
+\textit{file table} (il campo \var{f\_flag} di \var{file}), vengono in questo
+caso condivisi. Ai file però sono associati anche altri flag (l'unico usato al
+momento è \macro{FD\_CLOEXEC}), detti \textit{file descriptor flags}, tenuti
+invece in \var{file\_struct}; questi sono specifici di ciascun processo, e non
+vengono toccati anche in caso di condivisione della voce della \textit{file
+  table}.
 
-Si noti che i flag di stato del file, quelli settati dal parametro \var{flag}
-di \func{open}, essendo tenuti nella vode sulla file table, vengono condivisi,
-ai file sono però associati anche altri flag, (tenuti invece nella struttura
-\var{file\_struct} interna alla process table) che sono unici per ciascun file
-descriptor, e sono pertanto detti \textit{file descriptor flags} (l'unico
-usato al momento è \macro{FD\_CLOEXEC}).
 
 
 \subsection{Operazioni atomiche coi file}
 \label{sec:file_atomic}
 
+Come si è visto in un sistema unix è sempre possibile per più processi
+accedere in contemporanea allo stesso file, e che le operazioni di lettura e
+scrittura saranno fatte in base alla posizione corrente nel file. Ovviamente
+senza prevedere opportuni meccanismi di sincronizzazione le operazioni
+potranno mescolarsi in maniera imprevedibile. L'unica garanzia è che se si è
+in modalità \macro{O\_APPEND} il sistema assicura che si scriva (con il
+procedimento appena esposto) sempre alla fine del file.
+
+
+
 
 \subsection{La funzioni \func{dup} e \func{dup2}}
 \label{sec:file_dup}
 
-\subsection{La funzione \func{fcntl}}
-\label{sec:file_fcntl}
 
-\subsection{La funzione \func{ioctl}}
-\label{sec:file_ioctl}
 
+\begin{figure}[htb]
+  \centering \includegraphics[width=14cm]{img/filedup.eps}
+  \caption{Schema dell'accesso ai file duplicati}
+  \label{fig:file_dup}
+\end{figure}
 
 
+\subsection{La funzione \func{fcntl}}
+\label{sec:file_fcntl}
 
+\subsection{La funzione \func{ioctl}}
+\label{sec:file_ioctl}