+I primi tre campi della struttura, \var{l\_whence}, \var{l\_start} e
+\var{l\_len}, servono a specificare la sezione del file a cui fa riferimento
+il blocco: \var{l\_start} specifica il byte di partenza, \var{l\_len} la
+lunghezza della sezione e infine \var{l\_whence} imposta il riferimento da cui
+contare \var{l\_start}. Il valore di \var{l\_whence} segue la stessa semantica
+dell'omonimo argomento di \func{lseek}, coi tre possibili valori
+\const{SEEK\_SET}, \const{SEEK\_CUR} e \const{SEEK\_END}, (si vedano le
+relative descrizioni in sez.~\ref{sec:file_lseek}).
+
+Si tenga presente che un \textit{file lock} può essere richiesto anche per una
+regione al di là della corrente fine del file, così che una eventuale
+estensione dello stesso resti coperta dal blocco. Inoltre se si specifica un
+valore nullo per \var{l\_len} il blocco si considera esteso fino alla
+dimensione massima del file; in questo modo è possibile bloccare una qualunque
+regione a partire da un certo punto fino alla fine del file, coprendo
+automaticamente quanto eventualmente aggiunto in coda allo stesso.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{F\_RDLCK} & Richiede un blocco condiviso (\textit{read lock}).\\
+ \const{F\_WRLCK} & Richiede un blocco esclusivo (\textit{write lock}).\\
+ \const{F\_UNLCK} & Richiede l'eliminazione di un \textit{file lock}.\\
+ \hline
+ \end{tabular}
+ \caption{Valori possibili per il campo \var{l\_type} di \struct{flock}.}
+ \label{tab:file_flock_type}
+\end{table}
+
+Il tipo di \textit{file lock} richiesto viene specificato dal campo
+\var{l\_type}, esso può assumere i tre valori definiti dalle costanti
+riportate in tab.~\ref{tab:file_flock_type}, che permettono di richiedere
+rispettivamente uno \textit{shared lock}, un \textit{esclusive lock}, e la
+rimozione di un blocco precedentemente acquisito. Infine il campo \var{l\_pid}
+viene usato solo in caso di lettura, quando si chiama \func{fcntl} con
+\const{F\_GETLK}, e riporta il \ids{PID} del processo che detiene il
+\textit{file lock}.
+
+Oltre a quanto richiesto tramite i campi di \struct{flock}, l'operazione
+effettivamente svolta dalla funzione è stabilita dal valore dall'argomento
+\param{cmd} che, come già riportato in sez.~\ref{sec:file_fcntl}, specifica
+l'azione da compiere; i valori relativi al \textit{file locking} sono tre:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\const{F\_GETLK}] verifica se il \textit{file lock} specificato dalla
+ struttura puntata da \param{lock} può essere acquisito: in caso negativo
+ sovrascrive la struttura \param{flock} con i valori relativi al blocco già
+ esistente che ne blocca l'acquisizione, altrimenti si limita a impostarne il
+ campo \var{l\_type} con il valore \const{F\_UNLCK}.
+\item[\const{F\_SETLK}] se il campo \var{l\_type} della struttura puntata da
+ \param{lock} è \const{F\_RDLCK} o \const{F\_WRLCK} richiede il
+ corrispondente \textit{file lock}, se è \const{F\_UNLCK} lo rilascia. Nel
+ caso la richiesta non possa essere soddisfatta a causa di un blocco
+ preesistente la funzione ritorna immediatamente con un errore di
+ \errcode{EACCES} o di \errcode{EAGAIN}.
+\item[\const{F\_SETLKW}] è identica a \const{F\_SETLK}, ma se la richiesta di
+ non può essere soddisfatta per la presenza di un altro blocco, mette il
+ processo in stato di attesa fintanto che il blocco precedente non viene
+ rilasciato. Se l'attesa viene interrotta da un segnale la funzione ritorna
+ con un errore di \errcode{EINTR}.
+\end{basedescript}
+
+Si noti che per quanto detto il comando \const{F\_GETLK} non serve a rilevare
+una presenza generica di blocco su un file, perché se ne esistono altri
+compatibili con quello richiesto, la funzione ritorna comunque impostando
+\var{l\_type} a \const{F\_UNLCK}. Inoltre a seconda del valore di
+\var{l\_type} si potrà controllare o l'esistenza di un qualunque tipo di
+blocco (se è \const{F\_WRLCK}) o di \textit{write lock} (se è
+\const{F\_RDLCK}). Si consideri poi che può esserci più di un blocco che
+impedisce l'acquisizione di quello richiesto (basta che le regioni si
+sovrappongano), ma la funzione ne riporterà sempre soltanto uno, impostando
+\var{l\_whence} a \const{SEEK\_SET} ed i valori \var{l\_start} e \var{l\_len}
+per indicare quale è la regione bloccata.
+
+Infine si tenga presente che effettuare un controllo con il comando
+\const{F\_GETLK} e poi tentare l'acquisizione con \const{F\_SETLK} non è una
+operazione atomica (un altro processo potrebbe acquisire un blocco fra le due
+chiamate) per cui si deve sempre verificare il codice di ritorno di
+\func{fcntl}\footnote{controllare il codice di ritorno delle funzioni invocate
+ è comunque una buona norma di programmazione, che permette di evitare un
+ sacco di errori difficili da tracciare proprio perché non vengono rilevati.}
+quando la si invoca con \const{F\_SETLK}, per controllare che il blocco sia
+stato effettivamente acquisito.
+
+\begin{figure}[!htb]
+ \centering \includegraphics[width=9cm]{img/file_lock_dead}
+ \caption{Schema di una situazione di \itindex{deadlock} \textit{deadlock}.}
+ \label{fig:file_flock_dead}
+\end{figure}
+
+Non operando a livello di interi file, il \textit{file locking} POSIX
+introduce un'ulteriore complicazione; consideriamo la situazione illustrata in
+fig.~\ref{fig:file_flock_dead}, in cui il processo A blocca la regione 1 e il
+processo B la regione 2. Supponiamo che successivamente il processo A richieda
+un lock sulla regione 2 che non può essere acquisito per il preesistente lock
+del processo 2; il processo 1 si bloccherà fintanto che il processo 2 non
+rilasci il blocco. Ma cosa accade se il processo 2 nel frattempo tenta a sua
+volta di ottenere un lock sulla regione A? Questa è una tipica situazione che
+porta ad un \itindex{deadlock} \textit{deadlock}, dato che a quel punto anche
+il processo 2 si bloccherebbe, e niente potrebbe sbloccare l'altro processo.
+Per questo motivo il kernel si incarica di rilevare situazioni di questo tipo,
+ed impedirle restituendo un errore di \errcode{EDEADLK} alla funzione che
+cerca di acquisire un blocco che porterebbe ad un \itindex{deadlock}
+\textit{deadlock}.
+
+Per capire meglio il funzionamento del \textit{file locking} in semantica
+POSIX (che differisce alquanto rispetto da quello di BSD, visto
+sez.~\ref{sec:file_flock}) esaminiamo più in dettaglio come viene gestito dal
+kernel. Lo schema delle strutture utilizzate è riportato in
+fig.~\ref{fig:file_posix_lock}; come si vede esso è molto simile all'analogo
+di fig.~\ref{fig:file_flock_struct}:\footnote{in questo caso nella figura si
+ sono evidenziati solo i campi di \kstruct{file\_lock} significativi per la
+ semantica POSIX, in particolare adesso ciascuna struttura contiene, oltre al
+ \ids{PID} del processo in \var{fl\_pid}, la sezione di file che viene
+ bloccata grazie ai campi \var{fl\_start} e \var{fl\_end}. La struttura è
+ comunque la stessa, solo che in questo caso nel campo \var{fl\_flags} è
+ impostato il bit \const{FL\_POSIX} ed il campo \var{fl\_file} non viene
+ usato.} il blocco è sempre associato \itindex{inode} all'inode, solo che in
+questo caso la titolarità non viene identificata con il riferimento ad una
+voce nella \itindex{file~table} \textit{file table}, ma con il valore del
+\ids{PID} del processo.
+
+\begin{figure}[!htb]
+ \centering \includegraphics[width=12cm]{img/file_posix_lock}
+ \caption{Schema dell'architettura del \textit{file locking}, nel caso
+ particolare del suo utilizzo secondo l'interfaccia standard POSIX.}
+ \label{fig:file_posix_lock}
+\end{figure}
+
+Quando si richiede un \textit{file lock} il kernel effettua una scansione di
+tutti i blocchi presenti sul file\footnote{scandisce cioè la
+ \itindex{linked~list} \textit{linked list} delle strutture
+ \kstruct{file\_lock}, scartando automaticamente quelle per cui
+ \var{fl\_flags} non è \const{FL\_POSIX}, così che le due interfacce restano
+ ben separate.} per verificare se la regione richiesta non si sovrappone ad
+una già bloccata, in caso affermativo decide in base al tipo di blocco, in
+caso negativo il nuovo blocco viene comunque acquisito ed aggiunto alla lista.
+
+Nel caso di rimozione invece questa viene effettuata controllando che il
+\ids{PID} del processo richiedente corrisponda a quello contenuto nel blocco.
+Questa diversa modalità ha delle conseguenze precise riguardo il comportamento
+dei \textit{file lock} POSIX. La prima conseguenza è che un \textit{file lock}
+POSIX non viene mai ereditato attraverso una \func{fork}, dato che il processo
+figlio avrà un \ids{PID} diverso, mentre passa indenne attraverso una
+\func{exec} in quanto il \ids{PID} resta lo stesso. Questo comporta che, al
+contrario di quanto avveniva con la semantica BSD, quando un processo termina
+tutti i \textit{file lock} da esso detenuti vengono immediatamente rilasciati.
+
+La seconda conseguenza è che qualunque file descriptor che faccia riferimento
+allo stesso file (che sia stato ottenuto con una \func{dup} o con una
+\func{open} in questo caso non fa differenza) può essere usato per rimuovere
+un blocco, dato che quello che conta è solo il \ids{PID} del processo. Da
+questo deriva una ulteriore sottile differenza di comportamento: dato che alla
+chiusura di un file i blocchi ad esso associati vengono rimossi, nella
+semantica POSIX basterà chiudere un file descriptor qualunque per cancellare
+tutti i blocchi relativi al file cui esso faceva riferimento, anche se questi
+fossero stati creati usando altri file descriptor che restano aperti.
+
+Dato che il controllo sull'accesso ai blocchi viene eseguito sulla base del
+\ids{PID} del processo, possiamo anche prendere in considerazione un altro
+degli aspetti meno chiari di questa interfaccia e cioè cosa succede quando si
+richiedono dei blocchi su regioni che si sovrappongono fra loro all'interno
+stesso processo. Siccome il controllo, come nel caso della rimozione, si basa
+solo sul \ids{PID} del processo che chiama la funzione, queste richieste
+avranno sempre successo.
+
+Nel caso della semantica BSD, essendo i lock relativi a tutto un file e non
+accumulandosi,\footnote{questa ultima caratteristica è vera in generale, se
+ cioè si richiede più volte lo stesso \textit{file lock}, o più blocchi sulla
+ stessa sezione di file, le richieste non si cumulano e basta una sola
+ richiesta di rilascio per cancellare il blocco.} la cosa non ha alcun
+effetto; la funzione ritorna con successo, senza che il kernel debba
+modificare la lista dei \textit{file lock}. In questo caso invece si possono
+avere una serie di situazioni diverse: ad esempio è possibile rimuovere con
+una sola chiamata più \textit{file lock} distinti (indicando in una regione
+che si sovrapponga completamente a quelle di questi ultimi), o rimuovere solo
+una parte di un blocco preesistente (indicando una regione contenuta in quella
+di un altro blocco), creando un buco, o coprire con un nuovo blocco altri
+\textit{file lock} già ottenuti, e così via, a secondo di come si
+sovrappongono le regioni richieste e del tipo di operazione richiesta. Il
+comportamento seguito in questo caso che la funzione ha successo ed esegue
+l'operazione richiesta sulla regione indicata; è compito del kernel
+preoccuparsi di accorpare o dividere le voci nella lista dei \textit{file
+ lock} per far si che le regioni bloccate da essa risultanti siano coerenti
+con quanto necessario a soddisfare l'operazione richiesta.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/Flock.c}
+ \end{minipage}
+ \normalsize
+ \caption{Sezione principale del codice del programma \file{Flock.c}.}
+ \label{fig:file_flock_code}
+\end{figure}
+
+Per fare qualche esempio sul \textit{file locking} si è scritto un programma che
+permette di bloccare una sezione di un file usando la semantica POSIX, o un
+intero file usando la semantica BSD; in fig.~\ref{fig:file_flock_code} è
+riportata il corpo principale del codice del programma, (il testo completo è
+allegato nella directory dei sorgenti, nel file \texttt{Flock.c}).
+
+La sezione relativa alla gestione delle opzioni al solito si è omessa, come la
+funzione che stampa le istruzioni per l'uso del programma, essa si cura di
+impostare le variabili \var{type}, \var{start} e \var{len}; queste ultime due
+vengono inizializzate al valore numerico fornito rispettivamente tramite gli
+switch \code{-s} e \cmd{-l}, mentre il valore della prima viene impostato con
+le opzioni \cmd{-w} e \cmd{-r} si richiede rispettivamente o un \textit{write
+ lock} o \textit{read lock} (i due valori sono esclusivi, la variabile
+assumerà quello che si è specificato per ultimo). Oltre a queste tre vengono
+pure impostate la variabile \var{bsd}, che abilita la semantica omonima quando
+si invoca l'opzione \cmd{-f} (il valore preimpostato è nullo, ad indicare la
+semantica POSIX), e la variabile \var{cmd} che specifica la modalità di
+richiesta del \textit{file lock} (bloccante o meno), a seconda dell'opzione
+\cmd{-b}.
+
+Il programma inizia col controllare (\texttt{\small 11--14}) che venga passato
+un argomento (il file da bloccare), che sia stato scelto (\texttt{\small
+ 15--18}) il tipo di blocco, dopo di che apre (\texttt{\small 19}) il file,
+uscendo (\texttt{\small 20--23}) in caso di errore. A questo punto il
+comportamento dipende dalla semantica scelta; nel caso sia BSD occorre
+reimpostare il valore di \var{cmd} per l'uso con \func{flock}; infatti il
+valore preimpostato fa riferimento alla semantica POSIX e vale rispettivamente
+\const{F\_SETLKW} o \const{F\_SETLK} a seconda che si sia impostato o meno la
+modalità bloccante.
+
+Nel caso si sia scelta la semantica BSD (\texttt{\small 25--34}) prima si
+controlla (\texttt{\small 27--31}) il valore di \var{cmd} per determinare se
+si vuole effettuare una chiamata bloccante o meno, reimpostandone il valore
+opportunamente, dopo di che a seconda del tipo di blocco al valore viene
+aggiunta la relativa opzione (con un OR aritmetico, dato che \func{flock}
+vuole un argomento \param{operation} in forma di maschera binaria. Nel caso
+invece che si sia scelta la semantica POSIX le operazioni sono molto più
+immediate, si prepara (\texttt{\small 36--40}) la struttura per il lock, e lo
+esegue (\texttt{\small 41}).
+
+In entrambi i casi dopo aver richiesto il blocco viene controllato il
+risultato uscendo (\texttt{\small 44--46}) in caso di errore, o stampando un
+messaggio (\texttt{\small 47--49}) in caso di successo. Infine il programma si
+pone in attesa (\texttt{\small 50}) finché un segnale (ad esempio un \cmd{C-c}
+dato da tastiera) non lo interrompa; in questo caso il programma termina, e
+tutti i blocchi vengono rilasciati.
+
+Con il programma possiamo fare varie verifiche sul funzionamento del
+\textit{file locking}; cominciamo con l'eseguire un \textit{read lock} su un
+file, ad esempio usando all'interno di un terminale il seguente comando:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -r Flock.c
+Lock acquired
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+il programma segnalerà di aver acquisito un blocco e si bloccherà; in questo
+caso si è usato il \textit{file locking} POSIX e non avendo specificato niente
+riguardo alla sezione che si vuole bloccare sono stati usati i valori
+preimpostati che bloccano tutto il file. A questo punto se proviamo ad
+eseguire lo stesso comando in un altro terminale, e avremo lo stesso
+risultato. Se invece proviamo ad eseguire un \textit{write lock} avremo:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -w Flock.c
+Failed lock: Resource temporarily unavailable
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+come ci aspettiamo il programma terminerà segnalando l'indisponibilità del
+blocco, dato che il file è bloccato dal precedente \textit{read lock}. Si noti
+che il risultato è lo stesso anche se si richiede il blocco su una sola parte
+del file con il comando:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -w -s0 -l10 Flock.c
+Failed lock: Resource temporarily unavailable
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+se invece blocchiamo una regione con:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -r -s0 -l10 Flock.c
+Lock acquired
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+una volta che riproviamo ad acquisire il \textit{write lock} i risultati
+dipenderanno dalla regione richiesta; ad esempio nel caso in cui le due
+regioni si sovrappongono avremo che:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -w -s5 -l15 Flock.c
+Failed lock: Resource temporarily unavailable
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+ed il blocco viene rifiutato, ma se invece si richiede una regione distinta
+avremo che:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -w -s11 -l15 Flock.c
+Lock acquired
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+ed il blocco viene acquisito. Se a questo punto si prova ad eseguire un
+\textit{read lock} che comprende la nuova regione bloccata in scrittura:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -r -s10 -l20 Flock.c
+Failed lock: Resource temporarily unavailable
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+come ci aspettiamo questo non sarà consentito.
+
+Il programma di norma esegue il tentativo di acquisire il lock in modalità non
+bloccante, se però usiamo l'opzione \cmd{-b} possiamo impostare la modalità
+bloccante, riproviamo allora a ripetere le prove precedenti con questa
+opzione:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -r -b -s0 -l10 Flock.c Lock acquired
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+il primo comando acquisisce subito un \textit{read lock}, e quindi non cambia
+nulla, ma se proviamo adesso a richiedere un \textit{write lock} che non potrà
+essere acquisito otterremo:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -w -s0 -l10 Flock.c
+\end{verbatim}%$
+\end{minipage}\vspace{1mm}
+\par\noindent
+il programma cioè si bloccherà nella chiamata a \func{fcntl}; se a questo
+punto rilasciamo il precedente blocco (terminando il primo comando un
+\texttt{C-c} sul terminale) potremo verificare che sull'altro terminale il
+blocco viene acquisito, con la comparsa di una nuova riga:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[piccardi@gont sources]$ ./flock -w -s0 -l10 Flock.c
+Lock acquired
+\end{verbatim}%$
+\end{minipage}\vspace{3mm}
+\par\noindent
+
+Un'altra cosa che si può controllare con il nostro programma è l'interazione
+fra i due tipi di blocco; se ripartiamo dal primo comando con cui si è
+ottenuto un blocco in lettura sull'intero file, possiamo verificare cosa
+succede quando si cerca di ottenere un blocco in scrittura con la semantica
+BSD:
+
+\vspace{1mm}
+\begin{minipage}[c]{12cm}
+\begin{verbatim}
+[root@gont sources]# ./flock -f -w Flock.c
+Lock acquired
+\end{verbatim}
+\end{minipage}\vspace{1mm}
+\par\noindent
+che ci mostra come i due tipi di blocco siano assolutamente indipendenti; per
+questo motivo occorre sempre tenere presente quale fra le due semantiche
+disponibili stanno usando i programmi con cui si interagisce, dato che i
+blocchi applicati con l'altra non avrebbero nessun effetto.
+
+
+
+\subsection{La funzione \func{lockf}}
+\label{sec:file_lockf}
+
+Abbiamo visto come l'interfaccia POSIX per il \textit{file locking} sia molto
+più potente e flessibile di quella di BSD, questo comporta anche una maggiore
+complessità per via delle varie opzioni da passare a \func{fcntl}. Per questo
+motivo è disponibile anche una interfaccia semplificata (ripresa da System V)
+che utilizza la funzione \funcd{lockf}, il cui prototipo è:
+\begin{prototype}{sys/file.h}{int lockf(int fd, int cmd, off\_t len)}
+
+ Applica, controlla o rimuove un \textit{file lock} sul file \param{fd}.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
+ errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EWOULDBLOCK}] non è possibile acquisire il lock, e si è
+ selezionato \const{LOCK\_NB}, oppure l'operazione è proibita perché il
+ file è mappato in memoria.
+ \item[\errcode{ENOLCK}] il sistema non ha le risorse per il blocco: ci
+ sono troppi segmenti di \textit{lock} aperti, si è esaurita la tabella
+ dei \textit{file lock}.
+ \end{errlist}
+ ed inoltre \errval{EBADF}, \errval{EINVAL}.
+ }
+\end{prototype}
+
+Il comportamento della funzione dipende dal valore dell'argomento \param{cmd},
+che specifica quale azione eseguire; i valori possibili sono riportati in
+tab.~\ref{tab:file_lockf_type}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{7cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{LOCK\_SH}& Richiede uno \textit{shared lock}. Più processi possono
+ mantenere un blocco condiviso sullo stesso file.\\
+ \const{LOCK\_EX}& Richiede un \textit{exclusive lock}. Un solo processo
+ alla volta può mantenere un blocco esclusivo su un file.\\
+ \const{LOCK\_UN}& Sblocca il file.\\
+ \const{LOCK\_NB}& Non blocca la funzione quando il blocco non è disponibile,
+ si specifica sempre insieme ad una delle altre operazioni
+ con un OR aritmetico dei valori.\\
+ \hline
+ \end{tabular}
+ \caption{Valori possibili per l'argomento \param{cmd} di \func{lockf}.}
+ \label{tab:file_lockf_type}
+\end{table}
+
+Qualora il blocco non possa essere acquisito, a meno di non aver specificato
+\const{LOCK\_NB}, la funzione si blocca fino alla disponibilità dello stesso.
+Dato che la funzione è implementata utilizzando \func{fcntl} la semantica
+delle operazioni è la stessa di quest'ultima (pertanto la funzione non è
+affatto equivalente a \func{flock}).
+
+
+
+\subsection{Il \textit{mandatory locking}}
+\label{sec:file_mand_locking}
+
+\itindbeg{mandatory~locking}
+
+Il \textit{mandatory locking} è una opzione introdotta inizialmente in SVr4,
+per introdurre un \textit{file locking} che, come dice il nome, fosse
+effettivo indipendentemente dai controlli eseguiti da un processo. Con il
+\textit{mandatory locking} infatti è possibile far eseguire il blocco del file
+direttamente al sistema, così che, anche qualora non si predisponessero le
+opportune verifiche nei processi, questo verrebbe comunque rispettato.
+
+Per poter utilizzare il \textit{mandatory locking} è stato introdotto un
+utilizzo particolare del bit \itindex{sgid~bit} \acr{sgid}. Se si ricorda
+quanto esposto in sez.~\ref{sec:file_special_perm}), esso viene di norma
+utilizzato per cambiare il \ids{GID} effettivo con cui viene eseguito un
+programma, ed è pertanto sempre associato alla presenza del permesso di
+esecuzione per il gruppo. Impostando questo bit su un file senza permesso di
+esecuzione in un sistema che supporta il \textit{mandatory locking}, fa sì che
+quest'ultimo venga attivato per il file in questione. In questo modo una
+combinazione dei permessi originariamente non contemplata, in quanto senza
+significato, diventa l'indicazione della presenza o meno del \textit{mandatory
+ locking}.\footnote{un lettore attento potrebbe ricordare quanto detto in
+ sez.~\ref{sec:file_perm_management} e cioè che il bit \acr{sgid} viene
+ cancellato (come misura di sicurezza) quando di scrive su un file, questo
+ non vale quando esso viene utilizzato per attivare il \textit{mandatory
+ locking}.}
+
+L'uso del \textit{mandatory locking} presenta vari aspetti delicati, dato che
+neanche l'amministratore può passare sopra ad un \textit{file lock}; pertanto
+un processo che blocchi un file cruciale può renderlo completamente
+inaccessibile, rendendo completamente inutilizzabile il sistema\footnote{il
+ problema si potrebbe risolvere rimuovendo il bit \itindex{sgid~bit}
+ \acr{sgid}, ma non è detto che sia così facile fare questa operazione con un
+ sistema bloccato.} inoltre con il \textit{mandatory locking} si può
+bloccare completamente un server NFS richiedendo una lettura su un file su cui
+è attivo un blocco. Per questo motivo l'abilitazione del \textit{mandatory
+ locking} è di norma disabilitata, e deve essere attivata filesystem per
+filesystem in fase di montaggio (specificando l'apposita opzione di
+\func{mount} riportata in sez.~\ref{sec:filesystem_mounting}), o con l'opzione
+\code{-o mand} per il comando omonimo).
+
+Si tenga presente inoltre che il \textit{mandatory locking} funziona solo
+sull'interfaccia POSIX di \func{fcntl}. Questo ha due conseguenze: che non si
+ha nessun effetto sui \textit{file lock} richiesti con l'interfaccia di
+\func{flock}, e che la granularità del blocco è quella del singolo byte, come
+per \func{fcntl}.
+
+La sintassi di acquisizione dei blocchi è esattamente la stessa vista in
+precedenza per \func{fcntl} e \func{lockf}, la differenza è che in caso di
+\textit{mandatory lock} attivato non è più necessario controllare la
+disponibilità di accesso al file, ma si potranno usare direttamente le
+ordinarie funzioni di lettura e scrittura e sarà compito del kernel gestire
+direttamente il \textit{file locking}.
+
+Questo significa che in caso di \textit{read lock} la lettura dal file potrà
+avvenire normalmente con \func{read}, mentre una \func{write} si bloccherà
+fino al rilascio del blocco, a meno di non aver aperto il file con
+\const{O\_NONBLOCK}, nel qual caso essa ritornerà immediatamente con un errore
+di \errcode{EAGAIN}.
+
+Se invece si è acquisito un \textit{write lock} tutti i tentativi di leggere o
+scrivere sulla regione del file bloccata fermeranno il processo fino al
+rilascio del blocco, a meno che il file non sia stato aperto con
+\const{O\_NONBLOCK}, nel qual caso di nuovo si otterrà un ritorno immediato
+con l'errore di \errcode{EAGAIN}.
+
+Infine occorre ricordare che le funzioni di lettura e scrittura non sono le
+sole ad operare sui contenuti di un file, e che sia \func{creat} che
+\func{open} (quando chiamata con \const{O\_TRUNC}) effettuano dei cambiamenti,
+così come \func{truncate}, riducendone le dimensioni (a zero nei primi due
+casi, a quanto specificato nel secondo). Queste operazioni sono assimilate a
+degli accessi in scrittura e pertanto non potranno essere eseguite (fallendo
+con un errore di \errcode{EAGAIN}) su un file su cui sia presente un qualunque
+blocco (le prime due sempre, la terza solo nel caso che la riduzione delle
+dimensioni del file vada a sovrapporsi ad una regione bloccata).
+
+L'ultimo aspetto della interazione del \textit{mandatory locking} con le
+funzioni di accesso ai file è quello relativo ai file mappati in memoria (che
+abbiamo trattato in sez.~\ref{sec:file_memory_map}); anche in tal caso
+infatti, quando si esegue la mappatura con l'opzione \const{MAP\_SHARED}, si
+ha un accesso al contenuto del file. Lo standard SVID prevede che sia
+impossibile eseguire il memory mapping di un file su cui sono presenti dei
+blocchi\footnote{alcuni sistemi, come HP-UX, sono ancora più restrittivi e lo
+ impediscono anche in caso di \textit{advisory locking}, anche se questo
+ comportamento non ha molto senso, dato che comunque qualunque accesso
+ diretto al file è consentito.} in Linux è stata però fatta la scelta
+implementativa\footnote{per i dettagli si possono leggere le note relative
+ all'implementazione, mantenute insieme ai sorgenti del kernel nel file
+ \file{Documentation/mandatory.txt}.} di seguire questo comportamento
+soltanto quando si chiama \func{mmap} con l'opzione \const{MAP\_SHARED} (nel
+qual caso la funzione fallisce con il solito \errcode{EAGAIN}) che comporta la
+possibilità di modificare il file.
+
+\itindend{file~locking}
+
+\itindend{mandatory~locking}
+
+
+\section{L'\textit{I/O multiplexing}}
+\label{sec:file_multiplexing}
+
+
+Uno dei problemi che si presentano quando si deve operare contemporaneamente
+su molti file usando le funzioni illustrate in
+cap.~\ref{cha:file_unix_interface} e cap.~\ref{cha:files_std_interface} è che
+si può essere bloccati nelle operazioni su un file mentre un altro potrebbe
+essere disponibile. L'\textit{I/O multiplexing} nasce risposta a questo
+problema. In questa sezione forniremo una introduzione a questa problematica
+ed analizzeremo le varie funzioni usate per implementare questa modalità di
+I/O.
+
+
+\subsection{La problematica dell'\textit{I/O multiplexing}}
+\label{sec:file_noblocking}
+
+Abbiamo visto in sez.~\ref{sec:sig_gen_beha}, affrontando la suddivisione fra
+\textit{fast} e \textit{slow} system call,\index{system~call~lente} che in
+certi casi le funzioni di I/O possono bloccarsi indefinitamente.\footnote{si
+ ricordi però che questo può accadere solo per le pipe, i socket ed alcuni
+ file di dispositivo\index{file!di~dispositivo}; sui file normali le funzioni
+ di lettura e scrittura ritornano sempre subito.} Ad esempio le operazioni
+di lettura possono bloccarsi quando non ci sono dati disponibili sul
+descrittore su cui si sta operando.
+
+Questo comportamento causa uno dei problemi più comuni che ci si trova ad
+affrontare nelle operazioni di I/O, che si verifica quando si deve operare con
+più file descriptor eseguendo funzioni che possono bloccarsi senza che sia
+possibile prevedere quando questo può avvenire (il caso più classico è quello
+di un server in attesa di dati in ingresso da vari client). Quello che può
+accadere è di restare bloccati nell'eseguire una operazione su un file
+descriptor che non è ``\textsl{pronto}'', quando ce ne potrebbe essere un
+altro disponibile. Questo comporta nel migliore dei casi una operazione
+ritardata inutilmente nell'attesa del completamento di quella bloccata, mentre
+nel peggiore dei casi (quando la conclusione della operazione bloccata dipende
+da quanto si otterrebbe dal file descriptor ``\textsl{disponibile}'') si
+potrebbe addirittura arrivare ad un \itindex{deadlock} \textit{deadlock}.
+
+Abbiamo già accennato in sez.~\ref{sec:file_open} che è possibile prevenire
+questo tipo di comportamento delle funzioni di I/O aprendo un file in
+\textsl{modalità non-bloccante}, attraverso l'uso del flag \const{O\_NONBLOCK}
+nella chiamata di \func{open}. In questo caso le funzioni di input/output
+eseguite sul file che si sarebbero bloccate, ritornano immediatamente,
+restituendo l'errore \errcode{EAGAIN}. L'utilizzo di questa modalità di I/O
+permette di risolvere il problema controllando a turno i vari file descriptor,
+in un ciclo in cui si ripete l'accesso fintanto che esso non viene garantito.
+Ovviamente questa tecnica, detta \itindex{polling} \textit{polling}, è
+estremamente inefficiente: si tiene costantemente impiegata la CPU solo per
+eseguire in continuazione delle system call che nella gran parte dei casi
+falliranno.
+
+Per superare questo problema è stato introdotto il concetto di \textit{I/O
+ multiplexing}, una nuova modalità di operazioni che consente di tenere sotto
+controllo più file descriptor in contemporanea, permettendo di bloccare un
+processo quando le operazioni volute non sono possibili, e di riprenderne
+l'esecuzione una volta che almeno una di quelle richieste sia effettuabile, in
+modo da poterla eseguire con la sicurezza di non restare bloccati.
+
+Dato che, come abbiamo già accennato, per i normali file su disco non si ha
+mai un accesso bloccante, l'uso più comune delle funzioni che esamineremo nei
+prossimi paragrafi è per i server di rete, in cui esse vengono utilizzate per
+tenere sotto controllo dei socket; pertanto ritorneremo su di esse con
+ulteriori dettagli e qualche esempio di utilizzo concreto in
+sez.~\ref{sec:TCP_sock_multiplexing}.
+
+
+\subsection{Le funzioni \func{select} e \func{pselect}}
+\label{sec:file_select}
+
+Il primo kernel unix-like ad introdurre una interfaccia per l'\textit{I/O
+ multiplexing} è stato BSD,\footnote{la funzione \func{select} è apparsa in
+ BSD4.2 e standardizzata in BSD4.4, ma è stata portata su tutti i sistemi che
+ supportano i socket, compreso le varianti di System V.} con la funzione
+\funcd{select}, il cui prototipo è:
+\begin{functions}
+ \headdecl{sys/time.h}
+ \headdecl{sys/types.h}
+ \headdecl{unistd.h}
+ \funcdecl{int select(int ndfs, fd\_set *readfds, fd\_set *writefds, fd\_set
+ *exceptfds, struct timeval *timeout)}
+
+ Attende che uno dei file descriptor degli insiemi specificati diventi
+ attivo.
+
+ \bodydesc{La funzione in caso di successo restituisce il numero di file
+ descriptor (anche nullo) che sono attivi, e -1 in caso di errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EBADF}] si è specificato un file descriptor sbagliato in uno
+ degli insiemi.
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+ \item[\errcode{EINVAL}] si è specificato per \param{ndfs} un valore negativo
+ o un valore non valido per \param{timeout}.
+ \end{errlist}
+ ed inoltre \errval{ENOMEM}.
+}
+\end{functions}
+
+La funzione mette il processo in stato di \textit{sleep} (vedi
+tab.~\ref{tab:proc_proc_states}) fintanto che almeno uno dei file descriptor
+degli insiemi specificati (\param{readfds}, \param{writefds} e
+\param{exceptfds}), non diventa attivo, per un tempo massimo specificato da
+\param{timeout}.
+
+\itindbeg{file~descriptor~set}
+
+Per specificare quali file descriptor si intende selezionare la funzione usa
+un particolare oggetto, il \textit{file descriptor set}, identificato dal tipo
+\type{fd\_set}, che serve ad identificare un insieme di file descriptor, in
+maniera analoga a come un \itindex{signal~set} \textit{signal set} (vedi
+sez.~\ref{sec:sig_sigset}) identifica un insieme di segnali. Per la
+manipolazione di questi \textit{file descriptor set} si possono usare delle
+opportune macro di preprocessore:
+\begin{functions}
+ \headdecl{sys/time.h}
+ \headdecl{sys/types.h}
+ \headdecl{unistd.h}
+ \funcdecl{void \macro{FD\_ZERO}(fd\_set *set)}
+ Inizializza l'insieme (vuoto).
+
+ \funcdecl{void \macro{FD\_SET}(int fd, fd\_set *set)}
+ Inserisce il file descriptor \param{fd} nell'insieme.
+
+ \funcdecl{void \macro{FD\_CLR}(int fd, fd\_set *set)}
+ Rimuove il file descriptor \param{fd} dall'insieme.
+
+ \funcdecl{int \macro{FD\_ISSET}(int fd, fd\_set *set)}
+ Controlla se il file descriptor \param{fd} è nell'insieme.
+\end{functions}
+
+In genere un \textit{file descriptor set} può contenere fino ad un massimo di
+\const{FD\_SETSIZE} file descriptor. Questo valore in origine corrispondeva
+al limite per il numero massimo di file aperti\footnote{ad esempio in Linux,
+ fino alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma da
+quando, come nelle versioni più recenti del kernel, questo limite è stato
+rimosso, esso indica le dimensioni massime dei numeri usati nei \textit{file
+ descriptor set}.\footnote{il suo valore, secondo lo standard POSIX
+ 1003.1-2001, è definito in \headfile{sys/select.h}, ed è pari a 1024.}
+
+Si tenga presente che i \textit{file descriptor set} devono sempre essere
+inizializzati con \macro{FD\_ZERO}; passare a \func{select} un valore non
+inizializzato può dar luogo a comportamenti non prevedibili; allo stesso modo
+usare \macro{FD\_SET} o \macro{FD\_CLR} con un file descriptor il cui valore
+eccede \const{FD\_SETSIZE} può dare luogo ad un comportamento indefinito.
+
+La funzione richiede di specificare tre insiemi distinti di file descriptor;
+il primo, \param{readfds}, verrà osservato per rilevare la disponibilità di
+effettuare una lettura,\footnote{per essere precisi la funzione ritornerà in
+ tutti i casi in cui la successiva esecuzione di \func{read} risulti non
+ bloccante, quindi anche in caso di \textit{end-of-file}; inoltre con Linux
+ possono verificarsi casi particolari, ad esempio quando arrivano dati su un
+ socket dalla rete che poi risultano corrotti e vengono scartati, può
+ accadere che \func{select} riporti il relativo file descriptor come
+ leggibile, ma una successiva \func{read} si blocchi.} il secondo,
+\param{writefds}, per verificare la possibilità di effettuare una scrittura ed
+il terzo, \param{exceptfds}, per verificare l'esistenza di eccezioni (come i
+dati urgenti \itindex{out-of-band} su un socket, vedi
+sez.~\ref{sec:TCP_urgent_data}).
+
+Dato che in genere non si tengono mai sotto controllo fino a
+\const{FD\_SETSIZE} file contemporaneamente la funzione richiede di
+specificare qual è il valore più alto fra i file descriptor indicati nei tre
+insiemi precedenti. Questo viene fatto per efficienza, per evitare di passare
+e far controllare al kernel una quantità di memoria superiore a quella
+necessaria. Questo limite viene indicato tramite l'argomento \param{ndfs}, che
+deve corrispondere al valore massimo aumentato di uno.\footnote{si ricordi che
+ i file descriptor sono numerati progressivamente a partire da zero, ed il
+ valore indica il numero più alto fra quelli da tenere sotto controllo;
+ dimenticarsi di aumentare di uno il valore di \param{ndfs} è un errore
+ comune.}
+
+Infine l'argomento \param{timeout}, espresso con una struttura di tipo
+\struct{timeval} (vedi fig.~\ref{fig:sys_timeval_struct}) specifica un tempo
+massimo di attesa prima che la funzione ritorni; se impostato a \val{NULL} la
+funzione attende indefinitamente. Si può specificare anche un tempo nullo
+(cioè una struttura \struct{timeval} con i campi impostati a zero), qualora si
+voglia semplicemente controllare lo stato corrente dei file descriptor.
+
+La funzione restituisce il numero di file descriptor pronti,\footnote{questo è
+ il comportamento previsto dallo standard, ma la standardizzazione della
+ funzione è recente, ed esistono ancora alcune versioni di Unix che non si
+ comportano in questo modo.} e ciascun insieme viene sovrascritto per
+indicare quali sono i file descriptor pronti per le operazioni ad esso
+relative, in modo da poterli controllare con \macro{FD\_ISSET}. Se invece si
+ha un timeout viene restituito un valore nullo e gli insiemi non vengono
+modificati. In caso di errore la funzione restituisce -1, ed i valori dei tre
+insiemi sono indefiniti e non si può fare nessun affidamento sul loro
+contenuto.
+
+\itindend{file~descriptor~set}
+
+Una volta ritornata la funzione si potrà controllare quali sono i file
+descriptor pronti ed operare su di essi, si tenga presente però che si tratta
+solo di un suggerimento, esistono infatti condizioni\footnote{ad esempio
+ quando su un socket arrivano dei dati che poi vengono scartati perché
+ corrotti.} in cui \func{select} può riportare in maniera spuria che un file
+descriptor è pronto in lettura, quando una successiva lettura si bloccherebbe.
+Per questo quando si usa \textit{I/O multiplexing} è sempre raccomandato l'uso
+delle funzioni di lettura e scrittura in modalità non bloccante.
+
+In Linux \func{select} modifica anche il valore di \param{timeout},
+impostandolo al tempo restante, quando la funzione viene interrotta da un
+segnale. In tal caso infatti si ha un errore di \errcode{EINTR}, ed occorre
+rilanciare la funzione; in questo modo non è necessario ricalcolare tutte le
+volte il tempo rimanente. Questo può causare problemi di portabilità sia
+quando si usa codice scritto su Linux che legge questo valore, sia quando si
+usano programmi scritti per altri sistemi che non dispongono di questa
+caratteristica e ricalcolano \param{timeout} tutte le volte.\footnote{in
+ genere questa caratteristica è disponibile nei sistemi che derivano da
+ System V e non è disponibile per quelli che derivano da BSD; lo standard
+ POSIX.1-2001 non permette questo comportamento.}
+
+Uno dei problemi che si presentano con l'uso di \func{select} è che il suo
+comportamento dipende dal valore del file descriptor che si vuole tenere sotto
+controllo. Infatti il kernel riceve con \param{ndfs} un limite massimo per
+tale valore, e per capire quali sono i file descriptor da tenere sotto
+controllo dovrà effettuare una scansione su tutto l'intervallo, che può anche
+essere molto ampio anche se i file descriptor sono solo poche unità; tutto ciò
+ha ovviamente delle conseguenze ampiamente negative per le prestazioni.
+
+Inoltre c'è anche il problema che il numero massimo dei file che si possono
+tenere sotto controllo, la funzione è nata quando il kernel consentiva un
+numero massimo di 1024 file descriptor per processo, adesso che il numero può
+essere arbitrario si viene a creare una dipendenza del tutto artificiale dalle
+dimensioni della struttura \type{fd\_set}, che può necessitare di essere
+estesa, con ulteriori perdite di prestazioni.
+
+Lo standard POSIX è rimasto a lungo senza primitive per l'\textit{I/O
+ multiplexing}, introdotto solo con le ultime revisioni dello standard (POSIX
+1003.1g-2000 e POSIX 1003.1-2001). La scelta è stata quella di seguire
+l'interfaccia creata da BSD, ma prevede che tutte le funzioni ad esso relative
+vengano dichiarate nell'header \headfile{sys/select.h}, che sostituisce i
+precedenti, ed inoltre aggiunge a \func{select} una nuova funzione
+\funcd{pselect},\footnote{il supporto per lo standard POSIX 1003.1-2001, ed
+ l'header \headfile{sys/select.h}, compaiono in Linux a partire dalle
+ \acr{glibc} 2.1. Le \acr{libc4} e \acr{libc5} non contengono questo header,
+ le \acr{glibc} 2.0 contengono una definizione sbagliata di \func{psignal},
+ senza l'argomento \param{sigmask}, la definizione corretta è presente dalle
+ \acr{glibc} 2.1-2.2.1 se si è definito \macro{\_GNU\_SOURCE} e nelle
+ \acr{glibc} 2.2.2-2.2.4 se si è definito \macro{\_XOPEN\_SOURCE} con valore
+ maggiore di 600.} il cui prototipo è:
+\begin{prototype}{sys/select.h}
+ {int pselect(int n, fd\_set *readfds, fd\_set *writefds, fd\_set *exceptfds,
+ struct timespec *timeout, sigset\_t *sigmask)}
+
+ Attende che uno dei file descriptor degli insiemi specificati diventi
+ attivo.
+
+ \bodydesc{La funzione in caso di successo restituisce il numero di file
+ descriptor (anche nullo) che sono attivi, e -1 in caso di errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EBADF}] si è specificato un file descriptor sbagliato in uno
+ degli insiemi.
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+ \item[\errcode{EINVAL}] si è specificato per \param{ndfs} un valore negativo
+ o un valore non valido per \param{timeout}.
+ \end{errlist}
+ ed inoltre \errval{ENOMEM}.}
+\end{prototype}
+
+La funzione è sostanzialmente identica a \func{select}, solo che usa una
+struttura \struct{timespec} (vedi fig.~\ref{fig:sys_timespec_struct}) per
+indicare con maggiore precisione il timeout e non ne aggiorna il valore in
+caso di interruzione.\footnote{in realtà la system call di Linux aggiorna il
+ valore al tempo rimanente, ma la funzione fornita dalle \acr{glibc} modifica
+ questo comportamento passando alla system call una variabile locale, in modo
+ da mantenere l'aderenza allo standard POSIX che richiede che il valore di
+ \param{timeout} non sia modificato.} Inoltre prende un argomento aggiuntivo
+\param{sigmask} che è il puntatore ad una maschera di segnali (si veda
+sez.~\ref{sec:sig_sigmask}). La maschera corrente viene sostituita da questa
+immediatamente prima di eseguire l'attesa, e ripristinata al ritorno della
+funzione.
+
+L'uso di \param{sigmask} è stato introdotto allo scopo di prevenire possibili
+\textit{race condition} \itindex{race~condition} quando ci si deve porre in
+attesa sia di un segnale che di dati. La tecnica classica è quella di
+utilizzare il gestore per impostare una \index{variabili!globali} variabile
+globale e controllare questa nel corpo principale del programma; abbiamo visto
+in sez.~\ref{sec:sig_example} come questo lasci spazio a possibili
+\itindex{race~condition} \textit{race condition}, per cui diventa essenziale
+utilizzare \func{sigprocmask} per disabilitare la ricezione del segnale prima
+di eseguire il controllo e riabilitarlo dopo l'esecuzione delle relative
+operazioni, onde evitare l'arrivo di un segnale immediatamente dopo il
+controllo, che andrebbe perso.
+
+Nel nostro caso il problema si pone quando oltre al segnale si devono tenere
+sotto controllo anche dei file descriptor con \func{select}, in questo caso si
+può fare conto sul fatto che all'arrivo di un segnale essa verrebbe interrotta
+e si potrebbero eseguire di conseguenza le operazioni relative al segnale e
+alla gestione dati con un ciclo del tipo:
+\includecodesnip{listati/select_race.c}
+qui però emerge una \itindex{race~condition} \textit{race condition}, perché
+se il segnale arriva prima della chiamata a \func{select}, questa non verrà
+interrotta, e la ricezione del segnale non sarà rilevata.
+
+Per questo è stata introdotta \func{pselect} che attraverso l'argomento
+\param{sigmask} permette di riabilitare la ricezione il segnale
+contestualmente all'esecuzione della funzione,\footnote{in Linux però, fino al
+ kernel 2.6.16, non era presente la relativa system call, e la funzione era
+ implementata nelle \acr{glibc} attraverso \func{select} (vedi \texttt{man
+ select\_tut}) per cui la possibilità di \itindex{race~condition}
+ \textit{race condition} permaneva; in tale situazione si può ricorrere ad una