X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileunix.tex;h=4ea7eb9895ea8e7787cb56cfe4a251fccf8d60ff;hp=56e70435f4d2934b1e1abdeffe54b4ce5e82e703;hb=06a411c6242a35082817a74e9a86ec226d8bf0e3;hpb=1fe9dd622fcc8e8c83de032cf8679806cf52359b diff --git a/fileunix.tex b/fileunix.tex index 56e7043..4ea7eb9 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 @@ -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 - 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}. \\ @@ -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 - 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 +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. -(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 +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 -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 +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 -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 @@ -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 - 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 @@ -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 - 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ù -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