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}.
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
\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
\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}
-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
-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
\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
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
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à
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