Sistemata la parte della allocazione della memoria, le variadic
[gapil.git] / fileadv.tex
index 2a32a3ebc2fed94c6aa55bd0e4331dab2129782f..16e7a7f820ccc0b123623ee9b5fe5c839d7c4a78 100644 (file)
@@ -8,6 +8,7 @@
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
+
 \chapter{La gestione avanzata dei file}
 \label{cha:file_advanced}
 In questo capitolo affronteremo le tematiche relative alla gestione avanzata
@@ -189,11 +190,12 @@ riportate in tab.~\ref{tab:file_flock_operation}.
 \end{table}
 
 I primi due valori, \const{LOCK\_SH} e \const{LOCK\_EX} permettono di
-richiedere un \textit{file lock}, ed ovviamente devono essere usati in maniera
-alternativa. Se si specifica anche \const{LOCK\_NB} la funzione non si
-bloccherà qualora il \textit{file lock} non possa essere acquisito, ma
-ritornerà subito con un errore di \errcode{EWOULDBLOCK}. Per rilasciare un
-\textit{file lock} si dovrà invece usare \const{LOCK\_UN}.
+richiedere un \textit{file lock} rispettivamente condiviso o esclusivo, ed
+ovviamente non possono essere usati insieme. Se con essi si specifica anche
+\const{LOCK\_NB} la funzione non si bloccherà qualora il \textit{file lock}
+non possa essere acquisito, ma ritornerà subito con un errore di
+\errcode{EWOULDBLOCK}. Per rilasciare un \textit{file lock} si dovrà invece
+usare direttamente const{LOCK\_UN}.
 
 Si tenga presente che non esiste una modalità per eseguire atomicamente un
 cambiamento del tipo di blocco (da \textit{shared lock} a \textit{esclusive
@@ -232,7 +234,7 @@ inode\index{inode},\footnote{in particolare, come accennato in
 dato che questo è l'unico riferimento in comune che possono avere due processi
 diversi che aprono lo stesso file.
 
-\begin{figure}[htb]
+\begin{figure}[!htb]
   \centering
   \includegraphics[width=15.5cm]{img/file_flock}
   \caption{Schema dell'architettura del \textit{file locking}, nel caso
@@ -331,9 +333,9 @@ che un \textit{file lock} fa sempre riferimento ad una regione, per cui si
 potrà avere un conflitto anche se c'è soltanto una sovrapposizione parziale
 con un'altra regione bloccata.
 
-\begin{figure}[!bht]
+\begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\textwidth}
     \includestruct{listati/flock.h}
   \end{minipage} 
   \normalsize 
@@ -431,7 +433,7 @@ chiamate) per cui si deve sempre verificare il codice di ritorno di
 quando la si invoca con \const{F\_SETLK}, per controllare che il blocco sia
 stato effettivamente acquisito.
 
-\begin{figure}[htb]
+\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}
@@ -469,8 +471,8 @@ 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
 \acr{pid} del processo.
 
-\begin{figure}[!bht]
-  \centering \includegraphics[width=13cm]{img/file_posix_lock}
+\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}
@@ -533,9 +535,9 @@ 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}[!htb]
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/Flock.c}
   \end{minipage} 
   \normalsize 
@@ -547,7 +549,7 @@ Per fare qualche esempio sul \textit{file locking} si è scritto un programma ch
 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).
+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
@@ -1171,13 +1173,14 @@ 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 variabile globale e controllare questa
-nel corpo principale del programma; abbiamo visto in
-sez.~\ref{sec:sig_example} come questo lasci spazio a possibili 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.
+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
@@ -1262,7 +1265,7 @@ strutture \struct{pollfd} a meno di non voler cambiare qualche condizione.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\textwidth}
     \includestruct{listati/pollfd.h}
   \end{minipage} 
   \normalsize 
@@ -1623,13 +1626,13 @@ indicare quale tipo di evento relativo ad \param{fd} si vuole che sia tenuto
 sotto controllo.  L'argomento viene ignorato con l'operazione
 \const{EPOLL\_CTL\_DEL}.\footnote{fino al kernel 2.6.9 era comunque richiesto
   che questo fosse un puntatore valido, anche se poi veniva ignorato; a
-  partire dal 2.6.9 si può specificare anche un valore \texttt{NULL} ma se si
+  partire dal 2.6.9 si può specificare anche un valore \val{NULL} ma se si
   vuole mantenere la compatibilità con le versioni precedenti occorre usare un
   puntatore valido.}
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\textwidth}
     \includestruct{listati/epoll_event.h}
   \end{minipage} 
   \normalsize 
@@ -1648,7 +1651,7 @@ definizione è riportata in fig.~\ref{fig:epoll_event}.
 Il primo campo, \var{events}, è una maschera binaria in cui ciascun bit
 corrisponde o ad un tipo di evento, o una modalità di notifica; detto campo
 deve essere specificato come OR aritmetico delle costanti riportate in
-tab.~\ref{tab:epoll_events}. Il secondo campo, \var{data}, è una \ctyp{union}
+tab.~\ref{tab:epoll_events}. Il secondo campo, \var{data}, è una \direct{union}
 che serve a identificare il file descriptor a cui si intende fare riferimento,
 ed in astratto può contenere un valore qualsiasi (specificabile in diverse
 forme) che ne permetta una indicazione univoca. Il modo più comune di usarlo
@@ -1907,7 +1910,7 @@ segnale o si aspetta che un file descriptor sia accessibile e nessuna delle
 rispettive funzioni consente di fare contemporaneamente entrambe le cose.
 
 Per risolvere questo problema nello sviluppo del kernel si è pensato di
-introdurre un meccanismo alternativo alla notifica dei segnali (esteso anche
+introdurre un meccanismo alternativo per la notifica dei segnali (esteso anche
 ad altri eventi generici) che, ispirandosi di nuovo alla filosofia di Unix per
 cui tutto è un file, consentisse di eseguire la notifica con l'uso di
 opportuni file descriptor.\footnote{ovviamente si tratta di una funzionalità
@@ -1972,8 +1975,8 @@ specificato tramite l'argomento \param{mask}. Questo deve essere passato come
 puntatore ad una maschera di segnali creata con l'uso delle apposite macro già
 illustrate in sez.~\ref{sec:sig_sigset}. La maschera deve indicare su quali
 segnali si intende operare con \func{signalfd}; l'elenco può essere modificato
-con una successiva chiamata a \func{signalfd}. Dato che \const{SIGKILL} e
-\const{SIGSTOP} non possono essere intercettati (e non prevedono neanche la
+con una successiva chiamata a \func{signalfd}. Dato che \signal{SIGKILL} e
+\signal{SIGSTOP} non possono essere intercettati (e non prevedono neanche la
 possibilità di un gestore) un loro inserimento nella maschera verrà ignorato
 senza generare errori. 
 
@@ -2074,7 +2077,7 @@ successivo con \func{fcntl}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\textwidth}
     \includestruct{listati/signalfd_siginfo.h}
   \end{minipage} 
   \normalsize 
@@ -2102,21 +2105,198 @@ illustrato in sez.~\ref{sec:sig_sigaction}.\footnote{si tenga presente però
   che per un bug i kernel fino al 2.6.25 non avvalorano correttamente i campi
   \var{ssi\_ptr} e \var{ssi\_int} per segnali inviati con \func{sigqueue}.}
 
+Come esempio di questa nuova interfaccia ed anche come esempio di applicazione
+della interfaccia di \itindex{epoll} \textit{epoll}, si è scritto un programma
+elementare che stampi sullo standard output sia quanto viene scritto da terzi
+su una \textit{named fifo}, che l'avvenuta ricezione di alcuni segnali.  Il
+codice completo si trova al solito nei sorgenti allegati alla guida (nel file
+\texttt{FifoReporter.c}).
+
+In fig.~\ref{fig:fiforeporter_code_init} si è riportata la parte iniziale del
+programma in cui vengono effettuate le varie inizializzazioni necessarie per
+l'uso di \itindex{epoll} \textit{epoll} e \func{signalfd}, a partire
+(\texttt{\small 12--16}) dalla definizione delle varie variabili e strutture
+necessarie. Al solito si è tralasciata la parte dedicata alla decodifica delle
+opzioni che consentono ad esempio di cambiare il nome del file associato alla
+fifo.
+
+\begin{figure}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/FifoReporter-init.c}
+  \end{minipage} 
+  \normalsize 
+  \caption{Sezione di inizializzazione del codice del programma
+    \file{FifoReporter.c}.}
+  \label{fig:fiforeporter_code_init}
+\end{figure}
+
+Il primo passo (\texttt{\small 19--20}) è la crezione di un file descriptor
+\texttt{epfd} di \itindex{epoll} \textit{epoll} con \func{epoll\_create} che è
+quello che useremo per il controllo degli altri.  É poi necessario
+disabilitare la ricezione dei segnali (nel caso \signal{SIGINT},
+\signal{SIGQUIT} e \signal{SIGTERM}) per i quali si vuole la notifica tramite
+file descriptor. Per questo prima li si inseriscono (\texttt{\small 22--25}) in
+una maschera di segnali \texttt{sigmask} che useremo con (\texttt{\small 26})
+\func{sigprocmask} per disabilitarli.  Con la stessa maschera si potrà per
+passare all'uso (\texttt{\small 28--29}) di \func{signalfd} per abilitare la
+notifica sul file descriptor \var{sigfd}. Questo poi (\texttt{\small 30--33})
+dovrà essere aggiunto con \func{epoll\_ctl} all'elenco di file descriptor
+controllati con \texttt{epfd}.
+
+Occorrerà infine (\texttt{\small 35--38}) creare la \textit{named fifo} se
+questa non esiste ed aprirla per la lettura (\texttt{\small 39--40}); una
+volta fatto questo sarà necessario aggiungere il relativo file descriptor
+(\var{fifofd}) a quelli osservati da \itindex{epoll} \textit{epoll} in maniera
+del tutto analoga a quanto fatto con quello relativo alla notifica dei
+segnali.
+
+\begin{figure}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/FifoReporter-main.c}
+  \end{minipage} 
+  \normalsize 
+  \caption{Ciclo principale del codice del programma \file{FifoReporter.c}.}
+  \label{fig:fiforeporter_code_body}
+\end{figure}
+
+Una volta completata l'inizializzazione verrà eseguito indefinitamente il
+ciclo principale del programma (\texttt{\small 2--45}) che si è riportato in
+fig.~\ref{fig:fiforeporter_code_body}, fintanto che questo non riceva un
+segnale di \texttt{SIGINT} (ad esempio con la pressione di \texttt{C-c}). Il
+ciclo prevede che si attenda (\texttt{\small 2--3}) la presenza di un file
+descriptor pronto in lettura con \func{epoll\_wait},\footnote{si ricordi che
+  entrambi i file descriptor \var{fifofd} e \var{sigfd} sono stati posti in
+  osservazioni per eventi di tipo \const{EPOLLIN}.} che si bloccherà fintanto
+che non siano stati scritti dati sulla fifo o che non sia arrivato un
+segnale.\footnote{per semplificare il codice non si è trattato il caso in cui
+  \func{epoll\_wait} viene interrotta da un segnale, assumendo che tutti
+  quelli che possano interessare siano stati predisposti per la notifica
+  tramite file descriptor, per gli altri si otterrà semplicemente l'uscita dal
+  programma.}
+
+Anche se in questo caso i file descriptor pronti possono essere al più due, si
+è comunque adottato un approccio generico in cui questi verranno letti
+all'interno di un opportuno ciclo (\texttt{\small 5--44}) sul numero
+restituito da \func{epoll\_wait}, esaminando i risultati presenti nel vettore
+\var{events} all'interno di una catena di condizionali alternativi sul valore
+del file descriptor riconosciuto come pronto.\footnote{controllando cioè a
+  quale dei due file descriptor possibili corrisponde il campo relativo,
+  \var{events[i].data.fd}.}
+
+Il primo condizionale (\texttt{\small 6--24}) è relativo al caso che si sia
+ricevuto un segnale e che il file descriptor pronto corrisponda
+(\texttt{\small 6}) a \var{sigfd}. Dato che in generale si possono ricevere
+anche notifiche relativi a più di un singolo segnale, si è scelto di leggere
+una struttura \const{signalfd\_siginfo} alla volta, eseguendo la lettura
+all'interno di un ciclo (\texttt{\small 8--24}) che prosegue fintanto che vi
+siano dati da leggere.
+
+Per questo ad ogni lettura si esamina (\texttt{\small 9--14}) se il valore di
+ritorno della funzione \func{read} è negativo, uscendo dal programma
+(\texttt{\small 11}) in caso di errore reale, o terminando il ciclo
+(\texttt{\small 13}) con un \texttt{break} qualora si ottenga un errore di
+\errcode{EAGAIN} per via dell'esaurimento dei dati.\footnote{si ricordi come
+  sia la fifo che il file descriptor per i segnali siano stati aperti in
+  modalità non-bloccante, come previsto per l’\textit{I/O multiplexing},
+  pertanto ci si aspetta di ricevere un errore di \errcode{EAGAIN} quando non
+  vi saranno più dati da leggere.}
+
+In presenza di dati invece il programma proseguirà l'esecuzione stampando
+(\texttt{\small 19--20}) il nome del segnale ottenuto all'interno della
+struttura \const{signalfd\_siginfo} letta in \var{siginf}\footnote{per la
+  stampa si è usato il vettore \var{sig\_names} a ciascun elemento del quale
+  corrisponde il nome del segnale avente il numero corrispondente, la cui
+  definizione si è omessa dal codice di fig.~\ref{fig:fiforeporter_code_init}
+  per brevità.} ed il \textit{pid} del processo da cui lo ha ricevuto; inoltre
+(\texttt{\small 21--24}) si controllerà anche se il segnale ricevuto è
+\var{SIGINT}, che si è preso come segnale da utilizzare per la terminazione
+del programma, che verrà eseguita dopo aver rimosso il file della \textit{name
+  fifo}.
+Il secondo condizionale (\texttt{\small 26--39}) è invece relativo al caso in
+cui ci siano dati pronti in lettura sulla fifo e che il file descriptor pronto
+corrisponda (\texttt{\small 26}) a \var{fifofd}. Di nuovo si effettueranno le
+letture in un ciclo (\texttt{\small 28--39}) ripetendole fin tanto che la
+funzione \func{read} non resituisce un errore di \errcode{EAGAIN}
+(\texttt{\small 29--35}).\footnote{il procedimento è lo stesso adottato per il
+  file descriptor associato al segnale, in cui si esce dal programma in caso
+  di errore reale, in questo caso però alla fine dei dati prima di uscire si
+  stampa anche (\texttt{\small 32}) un messaggio di chiusura.} Se invece vi
+sono dati validi letti dalla fifo si inserirà (\texttt{\small 36}) una
+terminazione di stringa sul buffer e si stamperà il tutto (\texttt{\small
+  37--38}) sullo \textit{standard output}. L'ultimo condizionale
+(\texttt{\small 40--44}) è semplicemente una condizione di cattura per una
+eventualità che comunque non dovrebbe mai verificarsi, e che porta alla uscita
+dal programma con una opportuna segnalazione di errore.
+
+A questo punto si potrà eseguire il comando lanciandolo su un terminale, ed
+osservarne le reazioni agli eventi generati da un altro terminale; lanciando
+il programma otterremo qualcosa del tipo:
+\begin{Verbatim}
+piccardi@hain:~/gapil/sources$ ./a.out 
+FifoReporter starting, pid 4568
+\end{Verbatim}
+%$
+e scrivendo qualcosa sull'altro terminale con:
+\begin{Verbatim}
+root@hain:~# echo prova > /tmp/reporter.fifo  
+\end{Verbatim}
+si otterrà:
+\begin{Verbatim}
+Message from fifo:
+prova
+end message
+\end{Verbatim}
+mentre inviando un segnale:
+\begin{Verbatim}
+root@hain:~# kill 4568
+\end{Verbatim}
+si avrà:
+\begin{Verbatim}
+Signal received:
+Got SIGTERM       
+From pid 3361
+\end{Verbatim}
+ed infine premendo \texttt{C-\bslash} sul terminale in cui è in esecuzione si
+vedrà:
+\begin{Verbatim}
+^\Signal received:
+Got SIGQUIT       
+From pid 0
+\end{Verbatim}
+e si potrà far uscire il programma con \texttt{C-c} ottenendo:
+\begin{Verbatim}
+^CSignal received:
+Got SIGINT        
+From pid 0
+SIGINT means exit
+\end{Verbatim}
+
+
 Lo stesso paradigma di notifica tramite file descriptor usato per i segnali è
-stato adottato anche per i timer; in questo caso, rispetto a quanto visto in
+stato adottato anche per i timer. In questo caso, rispetto a quanto visto in
 sez.~\ref{sec:sig_timer_adv}, la scadenza di un timer potrà essere letta da un
-file descriptor, senza dover ricorrere ad altri meccanismi di notifica come un
+file descriptor senza dover ricorrere ad altri meccanismi di notifica come un
 segnale o un \textit{thread}. Di nuovo questo ha il vantaggio di poter
 utilizzare le funzioni dell'\textit{I/O multiplexing} per attendere allo
-stesso tempo la disponibilità di dati o la ricezione scadenza di un
+stesso tempo la disponibilità di dati o la ricezione della scadenza di un
 timer.\footnote{in realtà per questo sarebbe già sufficiente \func{signalfd}
   per ricevere i segnali associati ai timer, ma la nuova interfaccia
-  semplifica notevolmente la gestione e diminuisce l'\textit{overhead}.}
-
-Le funzioni di questa interfaccia riprendono da vicino quelle introdotte da
-POSIX.1-2001 illustrate sez.~\ref{sec:sig_timer_adv}. La prima funzione, che
-consente di creare un \textit{timer} è \funcd{timerfd\_create}, il cui
-prototipo è:
+  semplifica notevolmente la gestione e consente di fare tutto con una sola
+  \textit{system call}.}
+
+Le funzioni di questa nuova interfaccia ricalcano da vicino la struttura delle
+analoghe versioni ordinarie introdotte con lo standard POSIX.1-2001, che
+abbiamo già illustrato in sez.~\ref{sec:sig_timer_adv}.\footnote{questa
+  interfaccia è stata introdotta in forma considerata difettosa con il kernel
+  2.6.22, per cui è stata immediatamente tolta nel successivo 2.6.23 e
+  reintrodotta in una forma considerata adeguata nel kernel 2.6.25, il
+  supporto nelle \acr{glibc} è stato introdotto a partire dalla versione
+  2.8.6, la versione del kernel 2.6.22, presente solo su questo kernel, non è
+  supportata e non deve essere usata.} La prima funzione prevista, quella che
+consente di creare un timer, è \funcd{timerfd\_create}, il cui prototipo è:
 \begin{prototype}{sys/timerfd.h} 
   {int timerfd\_create(int clockid, int flags)}
 
@@ -2128,7 +2308,7 @@ prototipo è:
   \begin{errlist}
   \item[\errcode{EINVAL}] l'argomento \param{clockid} non è
     \const{CLOCK\_MONOTONIC} o \const{CLOCK\_REALTIME}, o
-    l'argomento \param{flag} non è valido o diverso da zero per kernel
+    l'argomento \param{flag} non è valido, o è diverso da zero per kernel
     precedenti il 2.6.27.
   \item[\errcode{ENOMEM}] non c'è memoria sufficiente per creare un nuovo file
     descriptor di \func{signalfd}.
@@ -2140,42 +2320,139 @@ prototipo è:
 }
 \end{prototype}
 
-La funzione prende come primo argomento il tipo di orologio a cui il timer
-deve fare riferimento, il cui significato è già stato illustrato in
-tab.~\ref{tab:sig_timer_clockid_types}, ma i soli valori validi sono
-\const{CLOCK\_REALTIME} e \const{CLOCK\_MONOTONIC}. 
+La funzione prende come primo argomento un intero che indica il tipo di
+orologio a cui il timer deve fare riferimento, i valori sono gli stessi delle
+funzioni dello standard POSIX-1.2001 già illustrati in
+tab.~\ref{tab:sig_timer_clockid_types}, ma al momento i soli utilizzabili sono
+\const{CLOCK\_REALTIME} e \const{CLOCK\_MONOTONIC}. L'argomento \param{flags},
+come l'analogo di \func{signalfd}, consente di impostare i flag per l'I/O non
+bloccante ed il \textit{close-on-exec} sul file descriptor
+restituito,\footnote{esso è stato introdotto a partire dal kernel 2.6.27, per
+  le versioni precedenti deve essere passato un valore nullo.} e deve essere
+specificato come una maschera binaria delle costanti riportate in
+tab.~\ref{tab:timerfd_flags}.
 
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Valore}  & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{TFD\_NONBLOCK}& imposta sul file descriptor il flag di
+                           \const{O\_NONBLOCK} per renderlo non bloccante.\\ 
+    \const{TFD\_CLOEXEC}&  imposta il flag di \const{O\_CLOEXEC} per la
+                           chiusura automatica del file descriptor nella
+                           esecuzione di \func{exec}.\\
+    \hline    
+  \end{tabular}
+  \caption{Valori dell'argomento \param{flags} per la funzione
+    \func{timerfd\_create} che consentono di impostare i flag del file
+    descriptor.}  
+  \label{tab:timerfd_flags}
+\end{table}
 
-% TODO trattare qui eventfd, timerfd introdotte con il 2.6.22 
-% timerfd è stata tolta nel 2.6.23 e rifatta per bene nel 2.6.25
-% vedi: http://lwn.net/Articles/233462/
-%       http://lwn.net/Articles/245533/
-%       http://lwn.net/Articles/267331/
+In caso di successo la funzione restituisce un file descriptor sul quale
+verranno notificate le scadenze dei timer. Come per quelli restituiti da
+\func{signalfd} anche questo file descriptor segue la semantica dei sistemi
+unix-like, in particolare resta aperto attraverso una \func{exec},\footnote{a
+  meno che non si sia impostato il flag di \textit{close-on exec} con
+  \const{TFD\_CLOEXEC}.} e viene duplicato attraverso una \func{fork}; questa
+ultima caratteristica comporta però che anche il figlio può utilizzare i dati
+di un timer creato nel padre, a differenza di quanto avviene invece con i
+timer impostati con le funzioni ordinarie.\footnote{si ricordi infatti che,
+  come illustrato in sez.~\ref{sec:proc_fork}, allarmi, timer e segnali
+  pendenti nel padre vengono cancellati per il figlio dopo una \func{fork}.}
+
+Una volta creato il timer con \func{timerfd\_create} per poterlo utilizzare
+occorre \textsl{armarlo} impostandone un tempo di scadenza ed una eventuale
+periodicità di ripetizione, per farlo si usa la funzione omologa di
+\func{timer\_settime} per la nuova interfaccia; questa è
+\funcd{timerfd\_settime} ed il suo prototipo è:
+\begin{prototype}{sys/timerfd.h} 
+  {int timerfd\_settime(int fd, int flags,
+                           const struct itimerspec *new\_value,
+                           struct itimerspec *old\_value)}
 
+  Crea un timer associato ad un file descriptor per la notifica. 
+
+  \bodydesc{La funzione restituisce un numero di file descriptor in caso di
+    successo o $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno
+    dei valori:
+  \begin{errlist}
+  \item[\errcode{EBADF}] l'argomento \param{fd} non corrisponde ad un file
+    descriptor. 
+  \item[\errcode{EINVAL}] il file descriptor \param{fd} non è stato ottenuto
+    con \func{timerfd\_create}, o i valori di \param{flag} o dei campi
+    \var{tv\_nsec} in \param{new\_value} non sono validi.
+  \item[\errcode{EFAULT}] o \param{new\_value} o \param{old\_value} non sono
+    puntatori validi.
+  \end{errlist}
+}
+\end{prototype}
+
+In questo caso occorre indicare su quale timer si intende operare specificando
+come primo argomento il file descriptor ad esso associato, che deve essere
+stato ottenuto da una precedente chiamata a \func{timerfd\_create}. I restanti
+argomenti sono del tutto analoghi a quelli della omologa funzione
+\func{timer\_settime}, e prevedono l'uso di strutture \struct{itimerspec}
+(vedi fig.~\ref{fig:struct_itimerspec}) per le indicazioni di temporizzazione.
+
+I valori ed il significato di questi argomenti sono gli stessi che sono già
+stati illustrati in dettaglio in sez.~\ref{sec:sig_timer_adv} e non staremo a
+ripetere quanto detto in quell'occasione;\footnote{per brevità si ricordi che
+  con \param{new\_value.it\_value} si indica la prima scadenza del timer e
+  con \param{new\_value.it\_interval} la sua periodicità.}  l'unica differenza
+riguarda l'argomento \param{flags} che serve sempre ad indicare se il tempo di
+scadenza del timer è da considerarsi relativo o assoluto rispetto al valore
+corrente dell'orologio associato al timer, ma che in questo caso ha come
+valori possibili rispettivamente soltanto $0$ e
+\const{TFD\_TIMER\_ABSTIME}.\footnote{anche questo valore, che è l'analogo di
+  \const{TIMER\_ABSTIME} è l'unico attualmente possibile per \param{flags}.}
+
+L'ultima funzione prevista dalla nuova interfaccia è \funcd{timerfd\_gettime},
+che è l'analoga di \func{timer\_gettime}, il suo prototipo è:
+\begin{prototype}{sys/timerfd.h} 
+  {int timerfd\_gettime(int fd, struct itimerspec *curr\_value)}
+
+  Crea un timer associato ad un file descriptor per la notifica. 
+
+  \bodydesc{La funzione restituisce un numero di file descriptor in caso di
+    successo o $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno
+    dei valori:
+  \begin{errlist}
+  \item[\errcode{EBADF}] l'argomento \param{fd} non corrisponde ad un file
+    descriptor. 
+  \item[\errcode{EINVAL}] il file descriptor \param{fd} non è stato ottenuto
+    con \func{timerfd\_create}.
+  \item[\errcode{EFAULT}] o \param{curr\_value} non è un puntatore valido.
+  \end{errlist}
+}
+\end{prototype}
 
-\begin{figure}[!htb]
-  \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \includecodesample{listati/FifoReporter-init.c}
-  \end{minipage} 
-  \normalsize 
-  \caption{Sezione di inizializzazione del codice del programma
-    \file{FifoReporter.c}.}
-  \label{fig:fiforeporter_code}
-\end{figure}
 
 
 
-\begin{figure}[!htb]
-  \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \includecodesample{listati/FifoReporter-main.c}
-  \end{minipage} 
-  \normalsize 
-  \caption{Ciclo principale del codice del programma \file{FifoReporter.c}.}
-  \label{fig:fiforeporter_code}
-\end{figure}
 
+Questo infatti diverrà pronto in lettura per tutte le varie funzioni dell'I/O
+multiplexing in presenza di una o più scadenze del timer ad esso associato.
+
+Inoltre sarà possibile ottenere il numero di volte che il timer è scaduto
+dalla ultima impostazione
+
+che può essere
+usato per leggere le notifiche delle scadenze dei timer. Queste possono essere
+ottenute leggendo in maniera ordinaria il file descriptor con una \func{read}, 
+
+
+
+
+% TODO trattare qui eventfd, timerfd introdotte con il 2.6.22 
+% timerfd è stata tolta nel 2.6.23 e rifatta per bene nel 2.6.25
+% vedi: http://lwn.net/Articles/233462/
+%       http://lwn.net/Articles/245533/
+%       http://lwn.net/Articles/267331/
 
 
 \section{L'accesso \textsl{asincrono} ai file}
@@ -2217,7 +2494,7 @@ Quello che succede è che per tutti i file posti in questa modalità\footnote{si
   tenga presente però che essa non è utilizzabile con i file ordinari ma solo
   con socket, file di terminale o pseudo terminale, ed anche, a partire dal
   kernel 2.6, anche per fifo e pipe.} il sistema genera un apposito segnale,
-\const{SIGIO}, tutte le volte che diventa possibile leggere o scrivere dal
+\signal{SIGIO}, tutte le volte che diventa possibile leggere o scrivere dal
 file descriptor che si è posto in questa modalità. Inoltre è possibile, come
 illustrato in sez.~\ref{sec:file_fcntl}, selezionare con il comando
 \const{F\_SETOWN} di \func{fcntl} quale processo o quale gruppo di processi
@@ -2259,7 +2536,7 @@ sez.~\ref{sec:sig_sigaction}).
 Per far questo però occorre utilizzare le funzionalità dei segnali real-time
 (vedi sez.~\ref{sec:sig_real_time}) impostando esplicitamente con il comando
 \const{F\_SETSIG} di \func{fcntl} un segnale real-time da inviare in caso di
-I/O asincrono (il segnale predefinito è \const{SIGIO}). In questo caso il
+I/O asincrono (il segnale predefinito è \signal{SIGIO}). In questo caso il
 gestore, tutte le volte che riceverà \const{SI\_SIGIO} come valore del campo
 \var{si\_code}\footnote{il valore resta \const{SI\_SIGIO} qualunque sia il
   segnale che si è associato all'I/O, ed indica appunto che il segnale è stato
@@ -2277,7 +2554,7 @@ la coda.
 
 Se infatti si eccedono le dimensioni di quest'ultima, il kernel, non potendo
 più assicurare il comportamento corretto per un segnale real-time, invierà al
-suo posto un solo \const{SIGIO}, su cui si saranno accumulati tutti i segnali
+suo posto un solo \signal{SIGIO}, su cui si saranno accumulati tutti i segnali
 in eccesso, e si dovrà allora determinare con un ciclo quali sono i file
 diventati attivi. L'unico modo per essere sicuri che questo non avvenga è di
 impostare la lunghezza della coda dei segnali real-time ad una dimensione
@@ -2305,7 +2582,7 @@ classico non prevedeva alcun meccanismo per cui un processo possa essere
 \textsl{notificato} di eventuali modifiche avvenute su un file. Questo è il
 motivo per cui i demoni devono essere \textsl{avvisati} in qualche
 modo\footnote{in genere questo vien fatto inviandogli un segnale di
-  \const{SIGHUP} che, per una convenzione adottata dalla gran parte di detti
+  \signal{SIGHUP} che, per una convenzione adottata dalla gran parte di detti
   programmi, causa la rilettura della configurazione.} se il loro file di
 configurazione è stato modificato, perché possano rileggerlo e riconoscere le
 modifiche.
@@ -2346,9 +2623,9 @@ questo è un meccanismo che consente ad un processo, detto \textit{lease
 \textit{lease}.
 La notifica avviene in maniera analoga a come illustrato in precedenza per
 l'uso di \const{O\_ASYNC}: di default viene inviato al \textit{lease holder}
-il segnale \const{SIGIO}, ma questo segnale può essere modificato usando il
+il segnale \signal{SIGIO}, ma questo segnale può essere modificato usando il
 comando \const{F\_SETSIG} di \func{fcntl}.\footnote{anche in questo caso si
-  può rispecificare lo stesso \const{SIGIO}.} Se si è fatto questo\footnote{è
+  può rispecificare lo stesso \signal{SIGIO}.} Se si è fatto questo\footnote{è
   in genere è opportuno farlo, come in precedenza, per utilizzare segnali
   real-time.} e si è installato il gestore del segnale con \const{SA\_SIGINFO}
 si riceverà nel campo \var{si\_fd} della struttura \struct{siginfo\_t} il
@@ -2461,7 +2738,7 @@ un'altra interfaccia,\footnote{si ricordi che anche questa è una interfaccia
   stata definita la macro \macro{\_GNU\_SOURCE}.} chiamata \textit{dnotify},
 che consente di richiedere una notifica quando una directory, o uno qualunque
 dei file in essa contenuti, viene modificato.  Come per i \textit{file lease}
-la notifica avviene di default attraverso il segnale \const{SIGIO}, ma se ne
+la notifica avviene di default attraverso il segnale \signal{SIGIO}, ma se ne
 può utilizzare un altro.\footnote{e di nuovo, per le ragioni già esposte in
   precedenza, è opportuno che si utilizzino dei segnali real-time.} Inoltre,
 come in precedenza, si potrà ottenere nel gestore del segnale il file
@@ -2812,7 +3089,7 @@ modalità non bloccante) fino all'arrivo di almeno un evento.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\textwidth}
     \includestruct{listati/inotify_event.h}
   \end{minipage} 
   \normalsize 
@@ -2909,7 +3186,7 @@ funzioni di ausilio è riportato in fig.~\ref{fig:inotify_monitor_example}.
 
 \begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/inotify_monitor.c}
   \end{minipage}
   \normalsize
@@ -3035,6 +3312,8 @@ raggruppati in un solo evento.
 \subsection{L'interfaccia POSIX per l'I/O asincrono}
 \label{sec:file_asyncronous_io}
 
+% vedere anche http://davmac.org/davpage/linux/async-io.html
+
 Una modalità alternativa all'uso dell'\textit{I/O multiplexing} per gestione
 dell'I/O simultaneo su molti file è costituita dal cosiddetto \textsl{I/O
   asincrono}. Il concetto base dell'\textsl{I/O asincrono} è che le funzioni
@@ -3072,7 +3351,7 @@ disponibilità dell'interfaccia per l'I/O asincrono.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\textwidth}
     \includestruct{listati/aiocb.h}
   \end{minipage} 
   \normalsize 
@@ -3152,10 +3431,10 @@ Si tenga inoltre presente che deallocare la memoria indirizzata da
 operazione può dar luogo a risultati impredicibili, perché l'accesso ai vari
 campi per eseguire l'operazione può avvenire in un momento qualsiasi dopo la
 richiesta.  Questo comporta che non si devono usare per \param{aiocbp}
-variabili automatiche e che non si deve riutilizzare la stessa struttura per
-un'altra operazione fintanto che la precedente non sia stata ultimata. In
-generale per ogni operazione si deve utilizzare una diversa struttura
-\struct{aiocb}.
+\index{variabili!automatiche} variabili automatiche e che non si deve
+riutilizzare la stessa struttura per un'altra operazione fintanto che la
+precedente non sia stata ultimata. In generale per ogni operazione si deve
+utilizzare una diversa struttura \struct{aiocb}.
 
 Dato che si opera in modalità asincrona, il successo di \func{aio\_read} o
 \func{aio\_write} non implica che le operazioni siano state effettivamente
@@ -3507,7 +3786,7 @@ Il valore dell'argomento \param{prot} indica la protezione\footnote{come
   pagine di memoria reale, ed le modalità di accesso (lettura, esecuzione,
   scrittura); una loro violazione causa quella una \itindex{segment~violation}
   \textit{segment violation}, e la relativa emissione del segnale
-  \const{SIGSEGV}.} da applicare al segmento di memoria e deve essere
+  \signal{SIGSEGV}.} da applicare al segmento di memoria e deve essere
 specificato come maschera binaria ottenuta dall'OR di uno o più dei valori
 riportati in tab.~\ref{tab:file_mmap_prot}; il valore specificato deve essere
 compatibile con la modalità di accesso con cui si è aperto il file.
@@ -3563,7 +3842,7 @@ tab.~\ref{tab:file_mmap_flag}.
                              modifiche fatte alla regione mappata, in
                              questo caso dopo una scrittura, se non c'è più
                              memoria disponibile, si ha l'emissione di
-                             un \const{SIGSEGV}.\\
+                             un \signal{SIGSEGV}.\\
     \const{MAP\_LOCKED}    & Se impostato impedisce lo swapping delle pagine
                              mappate.\\
     \const{MAP\_GROWSDOWN} & Usato per gli \itindex{stack} \textit{stack}. 
@@ -3610,7 +3889,7 @@ piuttosto complessi, essi si possono comprendere solo tenendo presente che
 tutto quanto è comunque basato sul meccanismo della \index{memoria~virtuale}
 memoria virtuale. Questo comporta allora una serie di conseguenze. La più
 ovvia è che se si cerca di scrivere su una zona mappata in sola lettura si
-avrà l'emissione di un segnale di violazione di accesso (\const{SIGSEGV}),
+avrà l'emissione di un segnale di violazione di accesso (\signal{SIGSEGV}),
 dato che i permessi sul segmento di memoria relativo non consentono questo
 tipo di accesso.
 
@@ -3637,7 +3916,7 @@ verrà il file sarà mappato su un segmento di memoria che si estende fino al
 bordo della pagina successiva.
 
 In questo caso è possibile accedere a quella zona di memoria che eccede le
-dimensioni specificate da \param{length}, senza ottenere un \const{SIGSEGV}
+dimensioni specificate da \param{length}, senza ottenere un \signal{SIGSEGV}
 poiché essa è presente nello spazio di indirizzi del processo, anche se non è
 mappata sul file. Il comportamento del sistema è quello di restituire un
 valore nullo per quanto viene letto, e di non riportare su file quanto viene
@@ -3651,8 +3930,8 @@ quella della mappatura in memoria.
 In questa situazione, per la sezione di pagina parzialmente coperta dal
 contenuto del file, vale esattamente quanto visto in precedenza; invece per la
 parte che eccede, fino alle dimensioni date da \param{length}, l'accesso non
-sarà più possibile, ma il segnale emesso non sarà \const{SIGSEGV}, ma
-\const{SIGBUS}, come illustrato in fig.~\ref{fig:file_mmap_exceed}.
+sarà più possibile, ma il segnale emesso non sarà \signal{SIGSEGV}, ma
+\signal{SIGBUS}, come illustrato in fig.~\ref{fig:file_mmap_exceed}.
 
 Non tutti i file possono venire mappati in memoria, dato che, come illustrato
 in fig.~\ref{fig:file_mmap_layout}, la mappatura introduce una corrispondenza
@@ -4186,7 +4465,7 @@ essere letti o scritti ed in che quantità. Il primo campo della struttura,
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\textwidth}
     \includestruct{listati/iovec.h}
   \end{minipage} 
   \normalsize 
@@ -4259,7 +4538,7 @@ sez.~\ref{sec:file_read} e \ref{sec:file_write}); le due funzioni sono
     per \var{errno} anche i valori:
   \begin{errlist}
   \item[\errcode{EOVERFLOW}] \param{offset} ha un valore che non può essere
-    usato come \ctyp{off\_t}.
+    usato come \type{off\_t}.
   \item[\errcode{ESPIPE}] \param{fd} è associato ad un socket o una pipe.
   \end{errlist}
 }
@@ -4463,7 +4742,7 @@ definito la macro \macro{\_GNU\_SOURCE},\footnote{si ricordi che questa
     \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'operazione
       richiesta.
     \item[\errcode{ESPIPE}] o \param{off\_in} o \param{off\_out} non sono
-      \const{NULL} ma il corrispondente file descriptor è una \textit{pipe}.
+      \val{NULL} ma il corrispondente file descriptor è una \textit{pipe}.
     \end{errlist}
   }
 \end{functions}
@@ -4597,9 +4876,9 @@ file destinazione. Il passo successivo è aprire il file sorgente
 (\texttt{\small 18--22}), quello di destinazione (\texttt{\small 23--27}) ed
 infine (\texttt{\small 28--31}) la \textit{pipe} che verrà usata come buffer.
 
-\begin{figure}[!phtb]
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/splicecp.c}
   \end{minipage}
   \normalsize
@@ -4772,7 +5051,7 @@ allegati alla guida.
 
 \begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/tee.c}
   \end{minipage}
   \normalsize
@@ -4896,7 +5175,7 @@ nelle operazioni successive.
 
 Il concetto di \func{readahead} viene generalizzato nello standard
 POSIX.1-2001 dalla funzione \func{posix\_fadvise},\footnote{anche se
-  l'argomento \param{len} è stato modificato da \ctyp{size\_t} a \ctyp{off\_t}
+  l'argomento \param{len} è stato modificato da \type{size\_t} a \type{off\_t}
   nella revisione POSIX.1-2003 TC5.} che consente di ``\textsl{avvisare}'' il
 kernel sulle modalità con cui si intende accedere nel futuro ad una certa
 porzione di un file,\footnote{la funzione però è stata introdotta su Linux
@@ -5078,7 +5357,7 @@ Trattandosi di una funzione di servizio, ed ovviamente disponibile
 esclusivamente su Linux, inizialmente \funcd{fallocate} non era stata definita
 come funzione di libreria,\footnote{pertanto poteva essere invocata soltanto
   in maniera indiretta con l'ausilio di \func{syscall}, vedi
-  sez.~\ref{sec:intro_syscall}, come \code{long fallocate(int fd, int mode,
+  sez.~\ref{sec:proc_syscall}, come \code{long fallocate(int fd, int mode,
       loff\_t offset, loff\_t len)}.} ma a partire dalle \acr{glibc} 2.10 è
   stato fornito un supporto esplicito; il suo prototipo è:
 \begin{functions}
@@ -5130,11 +5409,6 @@ livello di kernel.
 
 
 
-%\subsection{L'utilizzo delle porte di I/O}
-%\label{sec:file_io_port}
-%
-% TODO l'I/O sulle porte di I/O 
-% consultare le manpage di ioperm, iopl e outb
 
 % TODO non so dove trattarli, ma dal 2.6.39 ci sono i file handle, vedi
 % http://lwn.net/Articles/432757/ 
@@ -5188,11 +5462,13 @@ livello di kernel.
 % LocalWords:  Jens Anxboe vmsplice seek ESPIPE GIFT TCP CORK MSG splicecp nr
 % LocalWords:  nwrite segs patch readahead posix fadvise TC advice FADV NORMAL
 % LocalWords:  SEQUENTIAL NOREUSE WILLNEED DONTNEED streaming fallocate EFBIG
-% LocalWords:  POLLRDHUP half close pwait Gb madvise MADV ahead REMOVE tmpfs
+% LocalWords:  POLLRDHUP half close pwait Gb madvise MADV ahead REMOVE tmpfs it
 % LocalWords:  DONTFORK DOFORK shmfs preadv pwritev syscall linux loff head XFS
 % LocalWords:  MERGEABLE EOVERFLOW prealloca hole FALLOC KEEP stat fstat union
 % LocalWords:  conditions sigwait CLOEXEC signalfd sizemask SIGKILL SIGSTOP ssi
-% LocalWords:  sigwaitinfo FifoReporter Windows ptr sigqueue
+% LocalWords:  sigwaitinfo FifoReporter Windows ptr sigqueue named timerfd TFD
+% LocalWords:  clockid CLOCK MONOTONIC REALTIME itimerspec interval
+% LocalWords:  ABSTIME gettime
 
 
 %%% Local Variables: