Avanti sul memory mapping
[gapil.git] / fileunix.tex
index 56e70435f4d2934b1e1abdeffe54b4ce5e82e703..4ea7eb9895ea8e7787cb56cfe4a251fccf8d60ff 100644 (file)
@@ -3,11 +3,12 @@
 
 
 Esamineremo in questo capitolo la prima delle due interfacce di programmazione
 
 
 Esamineremo in questo capitolo la prima delle due interfacce di programmazione
-per i file, quella dei \textit{file descriptor}, nativa di Unix. Questa è
-l'interfaccia di basso livello provvista direttamente dalle system call, che
-non prevede funzionalità evolute come la bufferizzazione o funzioni di lettura
-o scrittura formattata, e sulla quale è costruita anche l'interfaccia definita
-dallo standard ANSI C che affronteremo al \capref{cha:files_std_interface}.
+per i file, quella dei \textit{file descriptor}\index{file descriptor},
+nativa di Unix. Questa è l'interfaccia di basso livello provvista direttamente
+dalle system call, che non prevede funzionalità evolute come la
+bufferizzazione o funzioni di lettura o scrittura formattata, e sulla quale è
+costruita anche l'interfaccia definita dallo standard ANSI C che affronteremo
+al \capref{cha:files_std_interface}.
 
 
 
 
 
 
@@ -33,10 +34,10 @@ terminate le operazioni, il file dovr
 canale di comunicazione impedendo ogni ulteriore operazione.
 
 All'interno di ogni processo i file aperti sono identificati da un intero non
 canale di comunicazione impedendo ogni ulteriore operazione.
 
 All'interno di ogni processo i file aperti sono identificati da un intero non
-negativo, chiamato appunto \textit{file descriptor}. Quando un file viene
-aperto la funzione \func{open} restituisce questo numero, tutte le ulteriori
-operazioni saranno compiute specificando questo stesso valore come argomento
-alle varie funzioni dell'interfaccia.
+negativo, chiamato appunto \textit{file descriptor}\index{file descriptor}.
+Quando un file viene aperto la funzione \func{open} restituisce questo numero,
+tutte le ulteriori operazioni saranno compiute specificando questo stesso
+valore come argomento alle varie funzioni dell'interfaccia.
 
 Per capire come funziona il meccanismo occorre spiegare a grandi linee come è
 che il kernel gestisce l'interazione fra processi e file.  Il kernel mantiene
 
 Per capire come funziona il meccanismo occorre spiegare a grandi linee come è
 che il kernel gestisce l'interazione fra processi e file.  Il kernel mantiene
@@ -56,8 +57,8 @@ particolare:
 \item una tabella che contiene un puntatore alla relativa voce nella
   \textit{file table} per ogni file aperto.
 \end{itemize*}
 \item una tabella che contiene un puntatore alla relativa voce nella
   \textit{file table} per ogni file aperto.
 \end{itemize*}
-il \textit{file descriptor} in sostanza è l'intero positivo che indicizza
-quest'ultima tabella.
+il \textit{file descriptor}\index{file descriptor} in sostanza è l'intero
+positivo che indicizza quest'ultima tabella.
 
 La \textit{file table} è una tabella che contiene una voce per ciascun file
 che è stato aperto nel sistema. In Linux è costituita da strutture di tipo
 
 La \textit{file table} è una tabella che contiene una voce per ciascun file
 che è stato aperto nel sistema. In Linux è costituita da strutture di tipo
@@ -87,23 +88,23 @@ varie strutture di dati sulla quale essa 
 \end{figure}
 Ritorneremo su questo schema più volte, dato che esso è fondamentale per
 capire i dettagli del funzionamento dell'interfaccia dei \textit{file
 \end{figure}
 Ritorneremo su questo schema più volte, dato che esso è fondamentale per
 capire i dettagli del funzionamento dell'interfaccia dei \textit{file
-  descriptor}.
+  descriptor}\index{file descriptor}.
 
 
 \subsection{I file standard}
 \label{sec:file_std_descr}
 
 
 
 \subsection{I file standard}
 \label{sec:file_std_descr}
 
-Come accennato i \textit{file descriptor} non sono altro che un indice nella
-tabella dei file aperti di ciascun processo; per questo motivo essi vengono
-assegnati in successione tutte le volte che si apre un nuovo file (se non ne è
-stato chiuso nessuno in precedenza).
+Come accennato i \textit{file descriptor}\index{file descriptor} non sono
+altro che un indice nella tabella dei file aperti di ciascun processo; per
+questo motivo essi vengono assegnati in successione tutte le volte che si apre
+un nuovo file (se non ne è stato chiuso nessuno in precedenza).
 
 In tutti i sistemi unix-like esiste una convenzione generale per cui ogni
 processo viene lanciato con almeno tre file aperti. Questi, per quanto appena
 
 In tutti i sistemi unix-like esiste una convenzione generale per cui ogni
 processo viene lanciato con almeno tre file aperti. Questi, per quanto appena
-detto, avranno come \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à.
+detto, avranno come \textit{file descriptor}\index{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 a quello che viene chiamato \textit{standard
   input}. È cioè il file da cui il processo si aspetta di ricevere i dati in
 
 Il primo file è sempre associato a quello che viene chiamato \textit{standard
   input}. È cioè il file da cui il processo si aspetta di ricevere i dati in
@@ -251,7 +252,8 @@ sempre il file descriptor con il valore pi
     opzione è ignorata. \\
     \macro{O\_DIRECTORY} & se \var{pathname} non è una directory la chiamata
     fallisce. Questo flag è specifico di Linux ed è stato introdotto con il
     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\protect\footnotemark\ quando 
+    kernel 2.1.126 per evitare dei
+    \textit{DoS}\index{DoS}\protect\footnotemark\ 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}. \\
     \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}. \\
@@ -292,9 +294,9 @@ sempre il file descriptor con il valore pi
 
 \footnotetext[2]{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
 
 \footnotetext[2]{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.}  
+  lock possono incorrere in una race condition\index{race condition}.  Si
+  consiglia come alternativa di usare un file con un nome univoco e la
+  funzione \func{link} per verificarne l'esistenza.}
 
 \footnotetext[3]{\textit{Denial of Service}, si chiamano così attacchi miranti
   ad impedire un servizio causando una qualche forma di carico eccessivo per
 
 \footnotetext[3]{\textit{Denial of Service}, si chiamano così attacchi miranti
   ad impedire un servizio causando una qualche forma di carico eccessivo per
@@ -477,8 +479,8 @@ 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.
 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}, vedi
-\secref{sec:file_atomic}).
+(questa è una potenziale sorgente di 
+\textit{race condition}\index{race condition}, vedi \secref{sec:file_atomic}).
 
 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
 
 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
@@ -764,12 +766,14 @@ utilizzare meccanismi di sincronizzazione pi
 Un caso tipico di necessità di accesso condiviso in scrittura è quello in cui
 vari processi devono scrivere alla fine di un file (ad esempio un file di
 log). Come accennato in \secref{sec:file_lseek} settare la posizione alla fine
 Un caso tipico di necessità di accesso condiviso in scrittura è quello in cui
 vari processi devono scrivere alla fine di un file (ad esempio un file di
 log). Come accennato in \secref{sec:file_lseek} settare la posizione alla fine
-del file e poi scrivere può condurre ad una \textit{race condition}: infatti
-può succedere che un secondo processo scriva alla fine del file fra la
-\func{lseek} e la \func{write}; in questo caso, come abbiamo appena visto, il
-file sarà esteso, ma il nostro primo processo avrà ancora la posizione
-corrente settata con la \func{lseek} che non corrisponde più alla fine del
-file, e la successiva \func{write} sovrascriverà i dati del secondo processo.
+del file e poi scrivere può condurre ad una 
+\textit{race condition}\index{race condition}: 
+infatti può succedere che un secondo processo scriva alla fine
+del file fra la \func{lseek} e la \func{write}; in questo caso, come abbiamo
+appena visto, il file sarà esteso, ma il nostro primo processo avrà ancora la
+posizione corrente settata 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 system call in successione non è un'operazione
 atomica; il problema è stato risolto introducendo la modalità
@@ -783,8 +787,8 @@ Un altro caso tipico in cui 
 creare un file di lock, bloccandosi se il file esiste. In questo caso la
 sequenza logica porterebbe a verificare prima l'esistenza del file con una
 \func{stat} per poi crearlo con una \func{creat}; di nuovo avremmo la
 creare un file di lock, bloccandosi se il file esiste. In questo caso la
 sequenza logica porterebbe a verificare prima l'esistenza del file con una
 \func{stat} per poi crearlo con una \func{creat}; di nuovo avremmo la
-possibilità di una race condition da parte di un altro processo che crea lo
-stesso file fra il controllo e la creazione. 
+possibilità di una race condition\index{race condition} da parte di un altro
+processo che crea lo stesso file fra il controllo e la creazione.
 
 Per questo motivo sono stati introdotti pe \func{open} i due flag
 \macro{O\_CREAT} e \macro{O\_EXCL}. In questo modo l'operazione di controllo
 
 Per questo motivo sono stati introdotti pe \func{open} i due flag
 \macro{O\_CREAT} e \macro{O\_EXCL}. In questo modo l'operazione di controllo
@@ -997,8 +1001,9 @@ valori 
   di \tabref{tab:file_open_flags}). 
 \item[\macro{F\_SETFL}] setta il \textit{file status flag} al valore
   specificato da \param{arg}, possono essere settati solo i bit riportati
   di \tabref{tab:file_open_flags}). 
 \item[\macro{F\_SETFL}] setta il \textit{file status flag} al valore
   specificato da \param{arg}, possono essere settati solo i bit riportati
-  nella terza sezione di \tabref{tab:file_open_flags}.\footnote{NdA da
-    verificare.}
+  nella terza sezione di \tabref{tab:file_open_flags}.\footnote{la man page
+    riporta come settabili solo \macro{O\_APPEND}, \macro{O\_NONBLOCK} e
+    \macro{O\_ASYNC}.}
 \item[\macro{F\_GETLK}] se un file lock è attivo restituisce nella struttura
   \param{lock} la struttura \type{flock} che impedisce l'acquisizione del
   blocco, altrimenti setta il campo \var{l\_type} a \macro{F\_UNLCK} (per i
 \item[\macro{F\_GETLK}] se un file lock è attivo restituisce nella struttura
   \param{lock} la struttura \type{flock} che impedisce l'acquisizione del
   blocco, altrimenti setta il campo \var{l\_type} a \macro{F\_UNLCK} (per i
@@ -1034,13 +1039,17 @@ valori 
   del segnale come \var{sa\_sigaction} usando \macro{SA\_SIGINFO}, (vedi
   \secref{sec:sig_sigaction}), di rendere disponibili al manipolatore
   informazioni ulteriori informazioni riguardo il file che ha generato il
   del segnale come \var{sa\_sigaction} usando \macro{SA\_SIGINFO}, (vedi
   \secref{sec:sig_sigaction}), di rendere disponibili al manipolatore
   informazioni ulteriori informazioni riguardo il file che ha generato il
-  segnale attraverso i valori restituiti in \var{siginfo\_t} (come vedremo in
-  \secref{sec:file_asyncronous_io}).
+  segnale attraverso i valori restituiti in \type{siginfo\_t} (come vedremo in
+  \secref{sec:file_asyncronous_io}).\footnote{i due comandi \macro{F\_SETSIG}
+    e \macro{F\_GETSIG} sono una estensione specifica di Linux.}
 \end{basedescript}
 
 La maggior parte delle funzionalità di \func{fcntl} sono troppo avanzate per
 poter essere affrontate in dettaglio a questo punto; saranno riprese più
 \end{basedescript}
 
 La maggior parte delle funzionalità di \func{fcntl} sono troppo avanzate per
 poter essere affrontate in dettaglio a questo punto; saranno riprese più
-avanti quando affronteremo le problematiche ad esse relative.
+avanti quando affronteremo le problematiche ad esse relative (in particolare
+riprenderemo le tematiche relative all'I/O asincrono in
+\secref{sec:file_asyncronous_io} e quelle relative al \textit{file locking} in
+\secref{sec:file_locking}).
 
 Per determinare le modalità di accesso inoltre è necessario estrarre i bit di
 accesso (ottenuti con il comando \macro{F\_GETFL}); infatti la definizione
 
 Per determinare le modalità di accesso inoltre è necessario estrarre i bit di
 accesso (ottenuti con il comando \macro{F\_GETFL}); infatti la definizione