X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileunix.tex;h=37b090626418cd83b16726298ba994c89f3418b4;hp=56e70435f4d2934b1e1abdeffe54b4ce5e82e703;hb=81ff87c3e2a6ecd3e33867798cba0d27576f44d0;hpb=6c705d16151fa82874be6aced255d346c9d2bd7b diff --git a/fileunix.tex b/fileunix.tex index 56e7043..37b0906 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -3,11 +3,12 @@ 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 -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 @@ -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*} -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 @@ -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 - 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 @@ -292,9 +293,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 - 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 @@ -477,8 +478,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. -(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 @@ -764,12 +765,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 -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à @@ -783,8 +786,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 -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