Piccole correzioni e revisione di epoll e signalfd.
[gapil.git] / fileadv.tex
index 278b3037a467f2c2415a5ba701c20103162697fa..60a002b3e2f4769c897878ed68a891fb25c88354 100644 (file)
@@ -590,29 +590,29 @@ 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
+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
+  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
+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
+immediate si prepara (\texttt{\small 36-40}) la struttura per il lock, e lo
 si 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
+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.
@@ -942,49 +942,51 @@ che in certi casi le funzioni di I/O eseguite su un file descritor possono
 bloccarsi indefinitamente. Questo non avviene mai per i file normali, per i
 quali le funzioni di lettura e scrittura ritornano sempre subito, ma può
 avvenire per alcuni \index{file!di~dispositivo} file di dispositivo, come ad
-esempio una seriale, o con l'uso di file descriptor collegati a meccanismi di
-intercomunicazione come le \textit{pipe} (vedi sez.~\ref{sec:ipc_unix}) ed i
-socket (vedi sez.~\ref{sec:sock_socket_def}). In casi come questi ad esempio
-una operazione di lettura potrebbe bloccarsi se non ci sono dati disponibili
-sul descrittore su cui la si sta effettuando.
+esempio una seriale o un terminale, o con l'uso di file descriptor collegati a
+meccanismi di intercomunicazione come le \textit{pipe} (vedi
+sez.~\ref{sec:ipc_unix}) ed i socket (vedi sez.~\ref{sec:sock_socket_def}). In
+casi come questi ad esempio una operazione di lettura potrebbe bloccarsi se
+non ci sono dati disponibili sul descrittore su cui la si sta effettuando.
 
 Questo comportamento è alla radice di una delle problematiche più comuni che
-ci si trova ad affrontare nelle operazioni di I/O, la necessità di operare su
-su più file descriptor eseguendo funzioni che possono bloccarsi
-indefinitamente senza che sia possibile prevedere quando questo può avvenire;
-un caso classico è quello di un server di rete (tratteremo la problematica in
-dettaglio nella seconda parte della guida) in attesa di dati in ingresso
-prevenienti da vari client.
+ci si trova ad affrontare nella gestione delle operazioni di I/O: la necessità
+di operare su più file descriptor eseguendo funzioni che possono bloccarsi
+indefinitamente senza che sia possibile prevedere quando questo può
+avvenire. Un caso classico è quello di un server di rete (tratteremo la
+problematica in dettaglio nella seconda parte della guida) in attesa di dati
+in ingresso prevenienti da vari client.
 
 In un caso di questo tipo, se si andasse ad operare sui vari file descriptor
 aperti uno dopo l'altro, potrebbe accadere di restare bloccati nell'eseguire
 una lettura su uno di quelli che non è ``\textsl{pronto}'', quando ce ne
 potrebbe essere un altro con dati disponibili. 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
+quella bloccata, mentre nel peggiore dei casi, quando la conclusione
+dell'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_close} 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
+di lettura o scrittura 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}
+viene garantito. Ovviamente questa tecnica, detta \itindex{polling}
 \textit{polling}, è estremamente inefficiente: si tiene costantemente
 impiegata la CPU solo per eseguire in continuazione delle \textit{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.
+É appunto per superare questo problema è stato introdotto il concetto di
+\textit{I/O multiplexing}, una nuova modalità per la gestione dell'I/O che
+consente di tenere sotto controllo più file descriptor in contemporanea,
+permettendo di bloccare un processo quando le operazioni di lettura o
+scrittura non sono immediatamente effettuabili, e di riprenderne l'esecuzione
+una volta che almeno una di quelle che erano state richieste diventi
+possibile, 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
@@ -998,33 +1000,34 @@ sez.~\ref{sec:TCP_sock_multiplexing}.
 \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:
+  multiplexing} è stato BSD, con la funzione \funcd{select} che è apparsa in
+BSD4.2 ed è stata standardizzata in BSD4.4, in seguito è stata portata su
+tutti i sistemi che supportano i socket, compreso le varianti di System V ed
+inserita in POSIX.1-2001; il suo prototipo è:\footnote{l'header
+  \texttt{sys/select.h} è stato introdotto con POSIX.1-2001, è ed presente con
+  le \acr{glibc} a partire dalla versione 2.0, in precedenza, con le
+  \acr{libc4} e le \acr{libc5}, occorreva includere \texttt{sys/time.h},
+  \texttt{sys/types.h} e \texttt{unistd.h}.}
+
+\begin{funcproto}{
+\fhead{sys/select.h}
+\fdecl{int select(int ndfs, fd\_set *readfds, fd\_set *writefds, fd\_set
+    *exceptfds, \\
+\phantom{int select(}struct timeval *timeout)}
+\fdesc{Attende che uno fra i file descriptor degli insiemi specificati diventi
+  attivo.} 
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un 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{EBADF}] si è specificato un file descriptor non valido
+    (chiuso o con errori) 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}
+  ed inoltre \errval{ENOMEM} nel suo significato generico.}
+\end{funcproto}
 
 La funzione mette il processo in stato di \textit{sleep} (vedi
 tab.~\ref{tab:proc_proc_states}) fintanto che almeno uno dei file descriptor
@@ -1041,35 +1044,35 @@ 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.
+{\centering
+\vspace{3pt}
+\begin{funcbox}{
+\fhead{sys/select.h}
+\fdecl{void \macro{FD\_ZERO}(fd\_set *set)}
+\fdesc{Inizializza l'insieme (vuoto).} 
+\fdecl{void \macro{FD\_SET}(int fd, fd\_set *set)}
+\fdesc{Inserisce il file descriptor \param{fd} nell'insieme.} 
+\fdecl{void \macro{FD\_CLR}(int fd, fd\_set *set)}
+\fdesc{Rimuove il file descriptor \param{fd} dall'insieme.} 
+\fdecl{int \macro{FD\_ISSET}(int fd, fd\_set *set)}
+\fdesc{Controlla se il file descriptor \param{fd} è nell'insieme.} 
+}
+\end{funcbox}}
 
-  \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.}
+al limite per il numero massimo di file aperti (ad esempio in Linux, fino alla
+serie 2.0.x, c'era un limite di 256 file per processo), ma da quando, nelle
+versioni più recenti del kernel, questo limite è stato rimosso, esso indica le
+dimensioni massime dei numeri usati nei \textit{file descriptor set}, ed 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
+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.
 
@@ -1077,68 +1080,88 @@ 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,
+  bloccante, quindi anche in caso di \textit{end-of-file}.} 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
+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
+\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.
+deve corrispondere al valore massimo aumentato di uno. Si ricordi infatti 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 il puntatore ad 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, e così può essere utilizzata eseguire il \itindex{polling}
+\textit{polling} su un gruppo di file descriptor. Usare questo argomento con
+tutti i \textit{file descriptor set} vuoti è un modo portabile, disponibile
+anche su sistemi in cui non sono disponibili le funzioni avanzate di
+sez.~\ref{sec:sig_timer_adv}, per tenere un processo in stato di
+\textit{sleep} con precisioni inferiori al secondo.
+
+In caso di successo la funzione restituisce il numero di file descriptor
+pronti, seguendo il comportamento previsto dallo standard
+POSIX.1-2001,\footnote{si tenga però presente che esistono alcune versioni di
+  Unix che non si comportano in questo modo, restituendo un valore positivo
+  generico.}  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 scade il tempo indicato
+da \param{timout} viene restituito un valore nullo e i \textit{file descriptor
+  set} non vengono modificati. In caso di errore la funzione restituisce $-1$, i
+valori dei tre insiemi e di \param{timeout} sono indefiniti e non si può fare
+nessun affidamento sul loro contenuto; nelle versioni più recenti della
+funzione invece i \textit{file descriptor set} non vengono modificati anche in
+caso di errore.
+
+Si tenga presente infine che su Linux, in caso di programmazione
+\textit{multithread} se un file descriptor viene chiuso in un altro
+\textit{thread} rispetto a quello in cui si sta usando \func{select}, questa
+non subisce nessun effetto. In altre varianti di sistemi unix-like invece
+\func{select} ritorna indicando che il file descriptor è pronto, con
+conseguente possibile errore nel caso lo si usi senza che sia stato
+riaperto. Lo standard non prevede niente al riguardo e non si deve dare per
+assunto nessuno dei due comportamenti se si vogliono scrivere programmi
+portabili.
+
 
 \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.}
+Una volta ritornata la funzione, si potrà controllare quali sono i file
+descriptor pronti, ed operare su di essi. Si tenga presente però che
+\func{select} fornisce solo di un suggerimento, esistono infatti condizioni in
+cui \func{select} può riportare in maniera spuria che un file descriptor è
+pronto, ma l'esecuzione di una operazione di I/O si bloccherebbe: ad esempio
+con Linux questo avviene quando su un socket arrivano dei dati che poi vengono
+scartati perché corrotti (ma sono possibili pure altri casi); in tal caso pur
+risultando il relativo file descriptor pronto in lettura una successiva
+esecuzione di una \func{read} si bloccherebbe. Per questo motivo quando si usa
+l'\textit{I/O multiplexing} è sempre raccomandato l'uso delle funzioni di
+lettura e scrittura in modalità non bloccante.
+
+Su Linux quando la \textit{system call} \func{select} viene interrotta da un
+segnale modifica il valore nella struttura puntata da \param{timeout},
+impostandolo al tempo restante. In tal caso infatti si ha un errore di
+\errcode{EINTR} ed occorre rilanciare la funzione per proseguire l'attesa, ed
+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. 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 e per questo motivo le \acr{glibc} nascondono il comportamento
+passando alla \textit{system call} una copia dell'argomento \param{timeout}.
 
 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
@@ -1169,53 +1192,59 @@ precedenti, ed inoltre aggiunge a \func{select} una nuova funzione
   \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{funcproto}{
+\fhead{sys/select.h}
+\fdecl{int pselect(int n, fd\_set *readfds, fd\_set *writefds, 
+  fd\_set *exceptfds, \\ 
+\phantom{int pselect(}struct timespec *timeout, sigset\_t *sigmask)}
+\fdesc{Attende che uno dei file descriptor degli insiemi specificati diventi
+  attivo.} 
+}
+{La funzione ritorna il numero (anche nullo) di file descriptor che sono
+  attivi in caso di successo e $-1$ per un 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}
+   \end{errlist}
+   ed inoltre \errval{ENOMEM} nel suo significato generico.
+}
+\end{funcproto}
 
 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 \textit{system call} di Linux
-  aggiorna il valore al tempo rimanente, ma la funzione fornita dalle
-  \acr{glibc} modifica questo comportamento passando alla \textit{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
-\index{maschera~dei~segnali} 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
+caso di interruzione. In realtà anche in questo caso la \textit{system call}
+di Linux aggiorna il valore al tempo rimanente, ma la funzione fornita dalle
+\acr{glibc} modifica questo comportamento passando alla \textit{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. 
+
+Rispetto a \func{select} la nuova funzione prende un argomento
+aggiuntivo \param{sigmask}, un puntatore ad una \index{maschera~dei~segnali}
+maschera di segnali (si veda sez.~\ref{sec:sig_sigmask}).  Nell'esecuzione la
+maschera dei segnali corrente viene sostituita da quella così indicata
+immediatamente prima di eseguire l'attesa, e viene poi ripristinata al ritorno
+della funzione. L'uso di \param{sigmask} è stato introdotto allo scopo di
+prevenire possibili \textit{race condition} \itindex{race~condition} quando
+oltre alla presenza di dati sui file descriptor come nella \func{select}
+ordinaria, ci si deve porre in attesa anche dell'arrivo di un segnale.
+
+Come abbiamo visto in sez.~\ref{sec:sig_example} la tecnica classica per
+rilevare l'arrivo di un segnale è quella di utilizzare il gestore per
+impostare una \index{variabili!globali} variabile globale e controllare questa
+nel corpo principale del programma; abbiamo visto in quell'occasione 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
@@ -1251,20 +1280,24 @@ interruzione si potranno eseguire le relative operazioni.
 \label{sec:file_poll}
 
 Nello sviluppo di System V, invece di utilizzare l'interfaccia di
-\func{select}, che è una estensione tipica di BSD, è stata introdotta un'altra
-interfaccia, basata sulla funzione \funcd{poll},\footnote{la funzione è
-  prevista dallo standard XPG4, ed è stata introdotta in Linux come system
-  call a partire dal kernel 2.1.23 ed inserita nelle \acr{libc} 5.4.28.} il
+\func{select}, che è una estensione tipica di BSD, è stata introdotta una
+interfaccia completamente diversa, basata sulla funzione di sistema
+\funcd{poll},\footnote{la funzione è prevista dallo standard XPG4, ed è stata
+  introdotta in Linux come system call a partire dal kernel 2.1.23 ed inserita
+  nelle \acr{libc} 5.4.28, originariamente l'argomento \param{nfds} era di
+  tipo \ctyp{unsigned int}, la funzione è stata inserita nello standard
+  POSIX.1-2001 in cui è stato introdotto il tipo nativo \type{nfds\_t}.} il
 cui prototipo è:
-\begin{prototype}{sys/poll.h}
-  {int poll(struct pollfd *ufds, unsigned int nfds, int timeout)}
-  
-  La funzione attende un cambiamento di stato su un insieme di file
-  descriptor.
-  
-  \bodydesc{La funzione restituisce il numero di file descriptor con attività
-    in caso di successo, o 0 se c'è stato un timeout e -1 in caso di errore,
-    ed in quest'ultimo caso \var{errno} assumerà uno dei valori:
+
+\begin{funcproto}{
+\fhead{sys/poll.h}
+\fdecl{int poll(struct pollfd *ufds, nfds\_t nfds, int timeout)}
+\fdesc{Attende un cambiamento di stato su un insieme di file
+  descriptor.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un 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.
@@ -1272,8 +1305,8 @@ cui prototipo è:
   \item[\errcode{EINVAL}] il valore di \param{nfds} eccede il limite
     \const{RLIMIT\_NOFILE}.
   \end{errlist}
-  ed inoltre \errval{EFAULT} e \errval{ENOMEM}.}
-\end{prototype}
+  ed inoltre \errval{EFAULT} e \errval{ENOMEM} nel loro significato generico.}
+\end{funcproto}
 
 La funzione permette di tenere sotto controllo contemporaneamente \param{ndfs}
 file descriptor, specificati attraverso il puntatore \param{ufds} ad un
@@ -1281,8 +1314,19 @@ vettore di strutture \struct{pollfd}.  Come con \func{select} si può
 interrompere l'attesa dopo un certo tempo, questo deve essere specificato con
 l'argomento \param{timeout} in numero di millisecondi: un valore negativo
 indica un'attesa indefinita, mentre un valore nullo comporta il ritorno
-immediato (e può essere utilizzato per impiegare \func{poll} in modalità
-\textsl{non-bloccante}).
+immediato, e può essere utilizzato per impiegare \func{poll} in modalità
+\textsl{non-bloccante}.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.90\textwidth}
+    \includestruct{listati/pollfd.h}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \structd{pollfd}, utilizzata per specificare le
+    modalità di controllo di un file descriptor alla funzione \func{poll}.}
+  \label{fig:file_pollfd}
+\end{figure}
 
 Per ciascun file da controllare deve essere inizializzata una struttura
 \struct{pollfd} nel vettore indicato dall'argomento \param{ufds}.  La
@@ -1291,30 +1335,24 @@ prevede tre campi: in \var{fd} deve essere indicato il numero del file
 descriptor da controllare, in \var{events} deve essere specificata una
 maschera binaria di flag che indichino il tipo di evento che si vuole
 controllare, mentre in \var{revents} il kernel restituirà il relativo
-risultato.  Usando un valore negativo per \param{fd} la corrispondente
-struttura sarà ignorata da \func{poll}. Dato che i dati in ingresso sono del
+risultato. 
+
+Usando un valore negativo per \param{fd} la corrispondente struttura sarà
+ignorata da \func{poll} ed il campo \var{revents} verrà azzerato, questo
+consente di eliminare temporaneamente un file descriptor dalla lista senza
+dover modificare il vettore \param{ufds}. Dato che i dati in ingresso sono del
 tutto indipendenti da quelli in uscita (che vengono restituiti in
 \var{revents}) non è necessario reinizializzare tutte le volte il valore delle
 strutture \struct{pollfd} a meno di non voler cambiare qualche condizione.
 
-\begin{figure}[!htb]
-  \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
-    \includestruct{listati/pollfd.h}
-  \end{minipage} 
-  \normalsize 
-  \caption{La struttura \structd{pollfd}, utilizzata per specificare le
-    modalità di controllo di un file descriptor alla funzione \func{poll}.}
-  \label{fig:file_pollfd}
-\end{figure}
-
 Le costanti che definiscono i valori relativi ai bit usati nelle maschere
-binarie dei campi \var{events} e \var{revents} sono riportati in
+binarie dei campi \var{events} e \var{revents} sono riportate in
 tab.~\ref{tab:file_pollfd_flags}, insieme al loro significato. Le si sono
-suddivise in tre gruppi, nel primo gruppo si sono indicati i bit utilizzati
-per controllare l'attività in ingresso, nel secondo quelli per l'attività in
-uscita, mentre il terzo gruppo contiene dei valori che vengono utilizzati solo
-nel campo \var{revents} per notificare delle condizioni di errore. 
+suddivise in tre gruppi principali, nel primo gruppo si sono indicati i bit
+utilizzati per controllare l'attività in ingresso, nel secondo quelli per
+l'attività in uscita, infine il terzo gruppo contiene dei valori che vengono
+utilizzati solo nel campo \var{revents} per notificare delle condizioni di
+errore.
 
 \begin{table}[htb]
   \centering
@@ -1356,33 +1394,35 @@ nel campo \var{revents} per notificare delle condizioni di errore.
   dettagli in sez.~\ref{sec:TCP_shutdown}.}
 
 Il valore \const{POLLMSG} non viene utilizzato ed è definito solo per
-compatibilità con l'implementazione di SysV che usa gli
-\textit{stream};\footnote{essi sono una interfaccia specifica di SysV non
-  presente in Linux, e non hanno nulla a che fare con i file \textit{stream}
-  delle librerie standard del C.} è da questi che derivano i nomi di alcune
-costanti, in quanto per essi sono definite tre classi di dati:
-\textsl{normali}, \textit{prioritari} ed \textit{urgenti}.  In Linux la
-distinzione ha senso solo per i dati urgenti \itindex{out-of-band} dei socket
-(vedi sez.~\ref{sec:TCP_urgent_data}), ma su questo e su come \func{poll}
-reagisce alle varie condizioni dei socket torneremo in
+compatibilità con l'implementazione di System V che usa i cosiddetti
+``\textit{stream}''. Si tratta di una interfaccia specifica di SysV non
+presente in Linux, che non ha nulla a che fare con gli \textit{stream} delle
+librerie standard del C visti in sez.~\ref{sec:file_stream}. Da essa derivano
+i nomi di alcune costanti poiché per quegli \textit{stream} sono definite tre
+classi di dati: \textsl{normali}, \textit{prioritari} ed \textit{urgenti}.  In
+Linux la distinzione ha senso solo per i dati urgenti \itindex{out-of-band}
+dei socket (vedi sez.~\ref{sec:TCP_urgent_data}), ma su questo e su come
+\func{poll} reagisce alle varie condizioni dei socket torneremo in
 sez.~\ref{sec:TCP_serv_poll}, dove vedremo anche un esempio del suo utilizzo.
 
-Si tenga conto comunque che le costanti relative ai diversi tipi di dati
-normali e prioritari, vale a dire \const{POLLRDNORM}, \const{POLLWRNORM},
-\const{POLLRDBAND} e \const{POLLWRBAND} fanno riferimento alle implementazioni
-in stile SysV (in particolare le ultime due non vengono usate su Linux), e
-sono utilizzabili soltanto qualora si sia definita la macro
-\macro{\_XOPEN\_SOURCE}.\footnote{e ci si ricordi di farlo sempre in testa al
-  file, definirla soltanto prima di includere \headfile{sys/poll.h} non è
-  sufficiente.}
-
-In caso di successo funzione ritorna restituendo il numero di file (un valore
-positivo) per i quali si è verificata una delle condizioni di attesa richieste
-o per i quali si è verificato un errore, nel qual caso vengono utilizzati i
-valori di tab.~\ref{tab:file_pollfd_flags} esclusivi di \var{revents}. Un
-valore nullo indica che si è raggiunto il timeout, mentre un valore negativo
-indica un errore nella chiamata, il cui codice viene riportato al solito
-tramite \var{errno}.
+Le costanti relative ai diversi tipi di dati normali e prioritari che fanno
+riferimento alle implementazioni in stile System V sono \const{POLLRDNORM},
+\const{POLLWRNORM}, \const{POLLRDBAND} e \const{POLLWRBAND}. Le prime due sono
+equivalenti rispettivamente a \const{POLLIN} e \const{POLLOUT},
+\const{POLLRDBAND} non viene praticamente mai usata su Linux mentre
+\const{POLLWRBAND} ha senso solo sui socket. In ogni caso queste costanti sono
+utilizzabili soltanto qualora si sia definita la macro
+\macro{\_XOPEN\_SOURCE}.
+
+In caso di successo \func{poll} ritorna restituendo il numero di file (un
+valore positivo) per i quali si è verificata una delle condizioni di attesa
+richieste o per i quali si è verificato un errore, avvalorando i relativi bit
+di \var{revents}. In caso di errori sui file vengono utilizzati i valori della
+terza sezione di tab.~\ref{tab:file_pollfd_flags} che hanno significato solo
+per \var{revents} (se specificati in \var{events} vengono ignorati). Un valore
+di ritorno nullo indica che si è raggiunto il timeout, mentre un valore
+negativo indica un errore nella chiamata, il cui codice viene riportato al
+solito tramite \var{errno}.
 
 L'uso di \func{poll} consente di superare alcuni dei problemi illustrati in
 precedenza per \func{select}; anzitutto, dato che in questo caso si usa un
@@ -1390,11 +1430,10 @@ vettore di strutture \struct{pollfd} di dimensione arbitraria, non esiste il
 limite introdotto dalle dimensioni massime di un \itindex{file~descriptor~set}
 \textit{file descriptor set} e la dimensione dei dati passati al kernel
 dipende solo dal numero dei file descriptor che si vogliono controllare, non
-dal loro valore.\footnote{anche se usando dei bit un \textit{file descriptor
-    set} può essere più efficiente di un vettore di strutture \struct{pollfd},
-  qualora si debba osservare un solo file descriptor con un valore molto alto
-  ci si troverà ad utilizzare inutilmente un maggiore quantitativo di
-  memoria.}
+dal loro valore. Infatti, anche se usando dei bit un \textit{file descriptor
+  set} può essere più efficiente di un vettore di strutture \struct{pollfd},
+qualora si debba osservare un solo file descriptor con un valore molto alto ci
+si troverà ad utilizzare inutilmente un maggiore quantitativo di memoria.
 
 Inoltre con \func{select} lo stesso \itindex{file~descriptor~set} \textit{file
   descriptor set} è usato sia in ingresso che in uscita, e questo significa
@@ -1414,16 +1453,19 @@ prevista da nessuno standard; essa può essere utilizzata esclusivamente se si
 definisce la macro \macro{\_GNU\_SOURCE} ed ovviamente non deve essere usata
 se si ha a cuore la portabilità. La funzione è \funcd{ppoll}, ed il suo
 prototipo è:
-\begin{prototype}{sys/poll.h}
-  {int ppoll(struct pollfd *fds, nfds\_t nfds, const struct timespec *timeout,
-    const sigset\_t *sigmask)}
-  
-  La funzione attende un cambiamento di stato su un insieme di file
-  descriptor.
-  
-  \bodydesc{La funzione restituisce il numero di file descriptor con attività
-    in caso di successo, o 0 se c'è stato un timeout e -1 in caso di errore,
-    ed in quest'ultimo caso \var{errno} assumerà uno dei valori:
+
+\begin{funcproto}{
+\fhead{sys/poll.h}
+\fdecl{int ppoll(struct pollfd *fds, nfds\_t nfds, 
+  const struct timespec *timeout, \\
+\phantom{int ppoll(}const sigset\_t *sigmask)} 
+
+\fdesc{Attende un cambiamento di stato su un insieme di file descriptor.}
+}
+
+{La funzione ritorna il numero di file descriptor con attività in caso di
+  successo, $0$ se c'è stato un timeout e $-1$ per un 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.
@@ -1431,8 +1473,9 @@ prototipo è:
   \item[\errcode{EINVAL}] il valore di \param{nfds} eccede il limite
     \const{RLIMIT\_NOFILE}.
   \end{errlist}
-  ed inoltre \errval{EFAULT} e \errval{ENOMEM}.}
-\end{prototype}
+ed inoltre \errval{EFAULT} e \errval{ENOMEM} nel loro significato generico.
+}  
+\end{funcproto}
 
 La funzione ha lo stesso comportamento di \func{poll}, solo che si può
 specificare, con l'argomento \param{sigmask}, il puntatore ad una
@@ -1446,14 +1489,17 @@ del seguente codice:
 Eccetto per \param{timeout}, che come per \func{pselect} deve essere un
 puntatore ad una struttura \struct{timespec}, gli altri argomenti comuni con
 \func{poll} hanno lo stesso significato, e la funzione restituisce gli stessi
-risultati illustrati in precedenza. Come nel caso di \func{pselect} la system
-call che implementa \func{ppoll} restituisce, se la funzione viene interrotta
-da un segnale, il tempo mancante in \param{timeout}, e come per \func{pselect}
-la funzione di libreria fornita dalle \acr{glibc} maschera questo
-comportamento non modificando mai il valore di \param{timeout}.\footnote{anche
-  se in questo caso non esiste nessuno standard che richiede questo
-  comportamento.}
-
+risultati illustrati in precedenza. Come nel caso di \func{pselect} la
+\textit{system call} che implementa \func{ppoll} restituisce, se la funzione
+viene interrotta da un segnale, il tempo mancante in \param{timeout}, e come
+per \func{pselect} la funzione di libreria fornita dalle \acr{glibc} maschera
+questo comportamento non modificando mai il valore di \param{timeout} anche se
+in questo caso non esiste nessuno standard che richieda questo comportamento.
+
+Infine anche per \func{poll} e \func{ppoll} valgono le considerazioni relative
+alla possibilità di avere delle notificazione spurie della disponibilita di
+accesso ai file descriptor illustrate per \func{select} in
+sez.~\ref{sec:file_select}, che non staremo a ripetere qui.
 
 \subsection{L'interfaccia di \textit{epoll}}
 \label{sec:file_epoll}
@@ -1471,10 +1517,10 @@ da \func{poll} a trasferire i dati da e verso il kernel è proporzionale al
 numero di file descriptor osservati, non a quelli che presentano attività.
 
 Quando ci sono decine di migliaia di file descriptor osservati e migliaia di
-eventi al secondo,\footnote{il caso classico è quello di un server web di un
-  sito con molti accessi.} l'uso di \func{poll} comporta la necessità di
-trasferire avanti ed indietro da user space a kernel space la lunga lista
-delle strutture \struct{pollfd} migliaia di volte al secondo. A questo poi si
+eventi al secondo (il caso classico è quello di un server web di un sito con
+molti accessi) l'uso di \func{poll} comporta la necessità di trasferire avanti
+ed indietro da \textit{user space} a \textit{kernel space} una lunga lista di
+strutture \struct{pollfd} migliaia di volte al secondo. A questo poi si
 aggiunge il fatto che la maggior parte del tempo di esecuzione sarà impegnato
 ad eseguire una scansione su tutti i file descriptor tenuti sotto controllo
 per determinare quali di essi (in genere una piccola percentuale) sono
@@ -1483,13 +1529,12 @@ dell'interfaccia dell'\textit{I/O multiplexing} viene a costituire un collo di
 bottiglia che degrada irrimediabilmente le prestazioni.
 
 Per risolvere questo tipo di situazioni sono state ideate delle interfacce
-specialistiche\footnote{come \texttt{/dev/poll} in Solaris, o \texttt{kqueue}
-  in BSD.} il cui scopo fondamentale è quello di restituire solamente le
-informazioni relative ai file descriptor osservati che presentano una
-attività, evitando così le problematiche appena illustrate. In genere queste
-prevedono che si registrino una sola volta i file descriptor da tenere sotto
-osservazione, e forniscono un meccanismo che notifica quali di questi
-presentano attività.
+specialistiche (come \texttt{/dev/poll} in Solaris, o \texttt{kqueue} in BSD)
+il cui scopo fondamentale è quello di restituire solamente le informazioni
+relative ai file descriptor osservati che presentano una attività, evitando
+così le problematiche appena illustrate. In genere queste prevedono che si
+registrino una sola volta i file descriptor da tenere sotto osservazione, e
+forniscono un meccanismo che notifica quali di questi presentano attività.
 
 Le modalità con cui avviene la notifica sono due, la prima è quella classica
 (quella usata da \func{poll} e \func{select}) che viene chiamata \textit{level
@@ -1516,88 +1561,87 @@ il file descriptor sia tornato non essere pronto, si potrà ricevere una
 ulteriore notifica qualora ritornasse pronto.
 
 Nel caso di Linux al momento la sola interfaccia che fornisce questo tipo di
-servizio è \textit{epoll},\footnote{l'interfaccia è stata creata da Davide
-  Libenzi, ed è stata introdotta per la prima volta nel kernel 2.5.44, ma la
-  sua forma definitiva è stata raggiunta nel kernel 2.5.66.} anche se sono in
-discussione altre interfacce con le quali si potranno effettuare lo stesso
-tipo di operazioni;\footnote{al momento della stesura di queste note (Giugno
-  2007) un'altra interfaccia proposta è quella di \textit{kevent}, che
-  fornisce un sistema di notifica di eventi generico in grado di fornire le
-  stesse funzionalità di \textit{epoll}, esiste però una forte discussione
-  intorno a tutto ciò e niente di definito.}  \textit{epoll} è in grado di
-operare sia in modalità \textit{level triggered} che \textit{edge triggered}.
-
-La prima versione \textit{epoll} prevedeva l'apertura di uno speciale file di
-dispositivo, \texttt{/dev/epoll}, per ottenere un file descriptor da
-utilizzare con le funzioni dell'interfaccia,\footnote{il backporting
-  dell'interfaccia per il kernel 2.4, non ufficiale, utilizza sempre questo
-  file.} ma poi si è passati all'uso di apposite \textit{system call}.  Il
-primo passo per usare l'interfaccia di \textit{epoll} è pertanto quello
-ottenere detto file descriptor chiamando una delle funzioni
-\funcd{epoll\_create} e \funcd{epoll\_create1},\footnote{l'interfaccia di
-  \textit{epoll} è stata inserita nel kernel a partire dalla versione 2.5.44,
-  ed il supporto è stato aggiunto alle \acr{glibc} 2.3.2.} i cui prototipi
-sono:
-\begin{functions}
-  \headdecl{sys/epoll.h}
+servizio è chiamata \textit{epoll},\footnote{l'interfaccia è stata creata da
+  Davide Libenzi, ed è stata introdotta per la prima volta nel kernel 2.5.44,
+  ma la sua forma definitiva è stata raggiunta nel kernel 2.5.66, il supporto
+  è stato aggiunto nelle \acr{glibc} a partire dalla versione 2.3.2.} anche se
+sono state in discussione altre interfacce con le quali effettuare lo stesso
+tipo di operazioni; \textit{epoll} è in grado di operare sia in modalità
+\textit{level triggered} che \textit{edge triggered}.
+
+La prima versione di \textit{epoll} prevedeva l'apertura di uno speciale file
+di dispositivo, \texttt{/dev/epoll}, per ottenere un file descriptor da
+utilizzare con le funzioni dell'interfaccia ma poi si è passati all'uso di
+apposite \textit{system call}.  Il primo passo per usare l'interfaccia di
+\textit{epoll} è pertanto quello ottenere detto file descriptor chiamando una
+delle due funzioni di sistema \funcd{epoll\_create} e \funcd{epoll\_create1},
+i cui prototipi sono:
 
-  \funcdecl{int epoll\_create(int size)}
-  \funcdecl{int epoll\_create1(int flags)}
-  
-  Apre un file descriptor per \textit{epoll}.
-  
-  \bodydesc{Le funzioni restituiscono un file descriptor per \textit{epoll} in
-    caso di successo, o $-1$ in caso di errore, nel qual caso \var{errno}
-    assumerà uno dei valori:
+\begin{funcproto}{
+\fhead{sys/epoll.h}
+\fdecl{int epoll\_create(int size)}
+\fdecl{int epoll\_create1(int flags)}
+
+\fdesc{Apre un file descriptor per \textit{epoll}.}
+}
+{Le funzioni ritornano un file descriptor per \textit{epoll} in caso di
+  successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei
+  valori:
   \begin{errlist}
   \item[\errcode{EINVAL}] si è specificato un valore di \param{size} non
     positivo o non valido per \param{flags}.
-  \item[\errcode{ENFILE}] si è raggiunto il massimo di file descriptor aperti
-    nel sistema.
   \item[\errcode{EMFILE}] si è raggiunto il limite sul numero massimo di
     istanze di \textit{epoll} per utente stabilito da
     \sysctlfile{fs/epoll/max\_user\_instances}.
+  \item[\errcode{ENFILE}] si è raggiunto il massimo di file descriptor aperti
+    nel sistema.
   \item[\errcode{ENOMEM}] non c'è sufficiente memoria nel kernel per creare
     l'istanza.
   \end{errlist}
-}
-\end{functions}
+}  
+\end{funcproto}
 
 Entrambe le funzioni restituiscono un file descriptor speciale,\footnote{esso
   non è associato a nessun file su disco, inoltre a differenza dei normali
   file descriptor non può essere inviato ad un altro processo attraverso un
   socket locale (vedi sez.~\ref{sec:sock_fd_passing}).} detto anche
 \textit{epoll descriptor}, che viene associato alla infrastruttura utilizzata
-dal kernel per gestire la notifica degli eventi. Nel caso di
-\func{epoll\_create} l'argomento \param{size} serviva a dare l'indicazione del
-numero di file descriptor che si vorranno tenere sotto controllo, e costituiva
-solo un suggerimento per semplificare l'allocazione di risorse sufficienti,
-non un valore massimo.\footnote{ma a partire dal kernel 2.6.8 esso viene
-  totalmente ignorato e l'allocazione è sempre dinamica.}
-
-La seconda versione della funzione, \func{epoll\_create1} è stata
-introdotta\footnote{è disponibile solo a partire dal kernel 2.6.27.} come
-estensione della precedente, per poter passare dei flag di controllo come
-maschera binaria in fase di creazione del file descriptor. Al momento l'unico
-valore legale per \param{flags} (a parte lo zero) è \const{EPOLL\_CLOEXEC},
-che consente di impostare in maniera atomica sul file descriptor il flag di
-\itindex{close-on-exec} \textit{close-on-exec} (si veda il significato di
-\const{O\_CLOEXEC} in sez.~\ref{sec:file_open_close}), senza che sia
+dal kernel per gestire la notifica degli eventi. Una volta che se ne sia
+terminato l'uso si potranno rilasciare tutte le risorse allocate chiudendolo
+come ogni altro file descriptor con \func{close}.
+
+Nel caso di \func{epoll\_create} l'argomento \param{size} serviva a dare
+l'indicazione del numero di file descriptor che si vorranno tenere sotto
+controllo, e costituiva solo un suggerimento per semplificare l'allocazione di
+risorse sufficienti, non un valore massimo, ma a partire dal kernel 2.6.8 esso
+viene totalmente ignorato e l'allocazione è sempre dinamica.
+
+La seconda versione della funzione, \func{epoll\_create1} è stata introdotta
+come estensione della precedente (è disponibile solo a partire dal kernel
+2.6.27) per poter passare dei flag di controllo come maschera binaria in fase
+di creazione del file descriptor. Al momento l'unico valore legale
+per \param{flags} (a parte lo zero) è \const{EPOLL\_CLOEXEC}, che consente di
+impostare in maniera atomica sul file descriptor il flag di
+\itindex{close-on-exec} \textit{close-on-exec} (si è trattato il significato
+di \const{O\_CLOEXEC} in sez.~\ref{sec:file_open_close}), senza che sia
 necessaria una successiva chiamata a \func{fcntl}.
 
 Una volta ottenuto un file descriptor per \textit{epoll} il passo successivo è
 indicare quali file descriptor mettere sotto osservazione e quali operazioni
-controllare, per questo si deve usare la seconda funzione dell'interfaccia,
-\funcd{epoll\_ctl}, il cui prototipo è:
-\begin{prototype}{sys/epoll.h}
-  {int epoll\_ctl(int epfd, int op, int fd, struct epoll\_event *event)}
-  
-  Esegue le operazioni di controllo di \textit{epoll}.
-  
-  \bodydesc{La funzione restituisce $0$ in caso di successo o $-1$ in caso di
-    errore, nel qual caso \var{errno} assumerà uno dei valori:
+controllare, per questo si deve usare la seconda funzione di sistema
+dell'interfaccia, \funcd{epoll\_ctl}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/epoll.h}
+\fdecl{int epoll\_ctl(int epfd, int op, int fd, struct epoll\_event *event)}
+
+\fdesc{Esegue le operazioni di controllo di \textit{epoll}.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EBADF}] il file descriptor \param{epfd} o \param{fd} non sono
+  \item[\errcode{EBADF}] i file descriptor \param{epfd} o \param{fd} non sono
     validi.
   \item[\errcode{EEXIST}] l'operazione richiesta è \const{EPOLL\_CTL\_ADD} ma
     \param{fd} è già stato inserito in \param{epfd}.
@@ -1608,13 +1652,14 @@ controllare, per questo si deve usare la seconda funzione dell'interfaccia,
     \const{EPOLL\_CTL\_DEL} ma \param{fd} non è inserito in \param{epfd}.
   \item[\errcode{ENOMEM}] non c'è sufficiente memoria nel kernel gestire
     l'operazione richiesta.
-  \item[\errcode{EPERM}] il file \param{fd} non supporta \textit{epoll}.
   \item[\errcode{ENOSPC}] si è raggiunto il limite massimo di registrazioni
     per utente di file descriptor da osservare imposto da
     \sysctlfile{fs/epoll/max\_user\_watches}.
+  \item[\errcode{EPERM}] il file associato a \param{fd} non supporta l'uso di
+    \textit{epoll}.
   \end{errlist}
-}
-\end{prototype}
+  }  
+\end{funcproto}
 
 Il comportamento della funzione viene controllato dal valore dall'argomento
 \param{op} che consente di specificare quale operazione deve essere eseguita.
@@ -1640,7 +1685,8 @@ delle operazioni cui fanno riferimento.
                              \param{event}.\\
     \const{EPOLL\_CTL\_DEL}& Rimuove il file descriptor \param{fd} dalla lista
                              dei file controllati tramite \param{epfd}.\\
-    \hline    
+    \const{EPOLL\_CTL\_DISABLE}& da fare.\\
+   \hline    
   \end{tabular}
   \caption{Valori dell'argomento \param{op} che consentono di scegliere quale
     operazione di controllo effettuare con la funzione \func{epoll\_ctl}.} 
@@ -1670,7 +1716,7 @@ sotto controllo.  L'argomento viene ignorato con l'operazione
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{0.90\textwidth}
     \includestruct{listati/epoll_event.h}
   \end{minipage} 
   \normalsize 
@@ -1701,7 +1747,7 @@ identificazione del file descriptor.
 \begin{table}[htb]
   \centering
   \footnotesize
-  \begin{tabular}[c]{|l|p{8cm}|}
+  \begin{tabular}[c]{|l|p{10cm}|}
     \hline
     \textbf{Valore}  & \textbf{Significato} \\
     \hline
@@ -1730,7 +1776,8 @@ identificazione del file descriptor.
     \const{EPOLLET}     & Imposta la notifica in modalità \textit{edge
                             triggered} per il file descriptor associato.\\ 
     \const{EPOLLONESHOT}& Imposta la modalità \textit{one-shot} per il file
-                          descriptor associato.\footnotemark\\
+                          descriptor associato (questa modalità è disponibile
+                          solo a partire dal kernel 2.6.2).\\
     \hline    
   \end{tabular}
   \caption{Costanti che identificano i bit del campo \param{events} di
@@ -1742,9 +1789,6 @@ identificazione del file descriptor.
   ed è utile per riconoscere la chiusura di una connessione dall'altro capo
   quando si lavora in modalità \textit{edge triggered}.}
 
-\footnotetext[48]{questa modalità è disponibile solo a partire dal kernel
-  2.6.2.}
-
 % TODO aggiunto EPOLLWAKEUP con il 3.5
 
 
@@ -1780,33 +1824,35 @@ non è necessario usare \const{EPOLL\_CTL\_DEL}.
 Infine una particolare modalità di notifica è quella impostata con
 \const{EPOLLONESHOT}: a causa dell'implementazione di \textit{epoll} infatti
 quando si è in modalità \textit{edge triggered} l'arrivo in rapida successione
-di dati in blocchi separati\footnote{questo è tipico con i socket di rete, in
-  quanto i dati arrivano a pacchetti.} può causare una generazione di eventi
-(ad esempio segnalazioni di dati in lettura disponibili) anche se la
-condizione è già stata rilevata.\footnote{si avrebbe cioè una rottura della
-  logica \textit{edge triggered}.} 
+di dati in blocchi separati (questo è tipico con i socket di rete, in quanto i
+dati arrivano a pacchetti) può causare una generazione di eventi (ad esempio
+segnalazioni di dati in lettura disponibili) anche se la condizione è già
+stata rilevata (si avrebbe cioè una rottura della logica \textit{edge
+  triggered}).
 
 Anche se la situazione è facile da gestire, la si può evitare utilizzando
 \const{EPOLLONESHOT} per impostare la modalità \textit{one-shot}, in cui la
 notifica di un evento viene effettuata una sola volta, dopo di che il file
 descriptor osservato, pur restando nella lista di osservazione, viene
-automaticamente disattivato,\footnote{la cosa avviene contestualmente al
-  ritorno di \func{epoll\_wait} a causa dell'evento in questione.} e per
-essere riutilizzato dovrà essere riabilitato esplicitamente con una successiva
-chiamata con \const{EPOLL\_CTL\_MOD}.
+automaticamente disattivato (la cosa avviene contestualmente al ritorno di
+\func{epoll\_wait} a causa dell'evento in questione) e per essere riutilizzato
+dovrà essere riabilitato esplicitamente con una successiva chiamata con
+\const{EPOLL\_CTL\_MOD}.
 
 Una volta impostato l'insieme di file descriptor che si vogliono osservare con
 i relativi eventi, la funzione che consente di attendere l'occorrenza di uno
 di tali eventi è \funcd{epoll\_wait}, il cui prototipo è:
-\begin{prototype}{sys/epoll.h}
-  {int epoll\_wait(int epfd, struct epoll\_event * events, int maxevents, int
-    timeout)}
-  
-  Attende che uno dei file descriptor osservati sia pronto.
-  
-  \bodydesc{La funzione restituisce il numero di file descriptor pronti in
-    caso di successo o $-1$ in caso di errore, nel qual caso \var{errno}
-    assumerà uno dei valori:
+
+\begin{funcproto}{
+\fhead{sys/epoll.h}
+\fdecl{int epoll\_wait(int epfd, struct epoll\_event * events, int maxevents,
+  int timeout)}
+
+\fdesc{Attende che uno dei file descriptor osservati sia pronto.}
+}
+
+{La funzione ritorna il numero di file descriptor pronti in caso di successo e
+  $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
   \item[\errcode{EBADF}] il file descriptor \param{epfd} non è valido.
   \item[\errcode{EFAULT}] il puntatore \param{events} non è valido.
@@ -1815,8 +1861,8 @@ di tali eventi è \funcd{epoll\_wait}, il cui prototipo è:
   \item[\errcode{EINVAL}] il file descriptor \param{epfd} non è stato ottenuto
     con \func{epoll\_create}, o \param{maxevents} non è maggiore di zero.
   \end{errlist}
-}
-\end{prototype}
+}  
+\end{funcproto}
 
 La funzione si blocca in attesa di un evento per i file descriptor registrati
 nella lista di osservazione di \param{epfd} fino ad un tempo massimo
@@ -1829,10 +1875,10 @@ con l'argomento \param{maxevents}.
 La funzione ritorna il numero di eventi rilevati, o un valore nullo qualora
 sia scaduto il tempo massimo impostato con \param{timeout}. Per quest'ultimo,
 oltre ad un numero di millisecondi, si può utilizzare il valore nullo, che
-indica di non attendere e ritornare immediatamente,\footnote{anche in questo
-  caso il valore di ritorno sarà nullo.} o il valore $-1$, che indica
-un'attesa indefinita. L'argomento \param{maxevents} dovrà invece essere sempre
-un intero positivo.
+indica di non attendere e ritornare immediatamente (anche in questo caso il
+valore di ritorno sarà nullo) o il valore $-1$, che indica un'attesa
+indefinita. L'argomento \param{maxevents} dovrà invece essere sempre un intero
+positivo.
 
 Come accennato la funzione restituisce i suoi risultati nel vettore di
 strutture \struct{epoll\_event} puntato da \param{events}; in tal caso nel
@@ -1841,8 +1887,8 @@ eventi accaduti, mentre nel campo \var{data} sarà restituito il valore che era
 stato impostato per il file descriptor per cui si è verificato l'evento quando
 questo era stato registrato con le operazioni \const{EPOLL\_CTL\_MOD} o
 \const{EPOLL\_CTL\_ADD}, in questo modo il campo \var{data} consente di
-identificare il file descriptor.\footnote{ed è per questo che, come accennato,
-  è consuetudine usare per \var{data} il valore del file descriptor stesso.}
+identificare il file descriptor, ed è per questo che, come accennato, è
+consuetudine usare per \var{data} il valore del file descriptor stesso.
 
 Si ricordi che le occasioni per cui \func{epoll\_wait} ritorna dipendono da
 come si è impostata la modalità di osservazione (se \textit{level triggered} o
@@ -1871,21 +1917,24 @@ per fare questo di nuovo è necessaria una variante della funzione di attesa
 che consenta di reimpostare all'uscita una \index{maschera~dei~segnali}
 maschera di segnali, analoga alle estensioni \func{pselect} e \func{ppoll} che
 abbiamo visto in precedenza per \func{select} e \func{poll}; in questo caso la
-funzione si chiama \funcd{epoll\_pwait}\footnote{la funziona è stata
+funzione si chiama \funcd{epoll\_pwait}\footnote{la funzione è stata
   introdotta a partire dal kernel 2.6.19, ed è come tutta l'interfaccia di
   \textit{epoll}, specifica di Linux.} ed il suo prototipo è:
-\begin{prototype}{sys/epoll.h} 
-  {int epoll\_pwait(int epfd, struct epoll\_event * events, int maxevents, 
+
+\begin{funcproto}{
+\fhead{sys/epoll.h}
+\fdecl{int epoll\_pwait(int epfd, struct epoll\_event * events, int maxevents, 
     int timeout, const sigset\_t *sigmask)}
 
-  Attende che uno dei file descriptor osservati sia pronto, mascherando i
-  segnali. 
+\fdesc{Attende che uno dei file descriptor osservati sia pronto, mascherando
+    i segnali.}  }
 
-  \bodydesc{La funzione restituisce il numero di file descriptor pronti in
-    caso di successo o $-1$ in caso di errore, nel qual caso \var{errno}
-    assumerà uno dei valori già visti con \funcd{epoll\_wait}.
-}
-\end{prototype}
+{La funzione ritorna il numero di file descriptor pronti in caso di successo e
+  $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori già
+  visti con \funcd{epoll\_wait}.
+  
+}  
+\end{funcproto}
 
 La funzione è del tutto analoga \funcd{epoll\_wait}, soltanto che alla sua
 uscita viene ripristinata la \index{maschera~dei~segnali} maschera di segnali
@@ -1933,15 +1982,15 @@ risposte, mentre con l'arrivo di un segnale si possono avere interruzioni
 asincrone in qualunque momento.  Questo comporta la necessità di dover
 gestire, quando si deve tener conto di entrambi i tipi di eventi, le
 interruzioni delle funzioni di attesa sincrone, ed evitare possibili
-\itindex{race~condition} \textit{race conditions}.\footnote{in sostanza se non
-  fossero per i segnali non ci sarebbe da doversi preoccupare, fintanto che si
-  effettuano operazioni all'interno di un processo, della non atomicità delle
-  \index{system~call~lente} \textit{system call} lente che vengono interrotte
-  e devono essere riavviate.}
+\itindex{race~condition} \textit{race conditions}. In sostanza se non ci
+fossero i segnali non ci sarebbe da preoccuparsi, fintanto che si effettuano
+operazioni all'interno di un processo, della non atomicità delle
+\index{system~call~lente} \textit{system call} lente che vengono interrotte e
+devono essere riavviate.
 
 Abbiamo visto però in sez.~\ref{sec:sig_real_time} che insieme ai segnali
 \textit{real-time} sono state introdotte anche delle interfacce di gestione
-sincrona dei segnali con la funzione \func{sigwait} e le sue affini. Queste
+sincrona dei segnali, con la funzione \func{sigwait} e le sue affini. Queste
 funzioni consentono di gestire i segnali bloccando un processo fino alla
 avvenuta ricezione e disabilitando l'esecuzione asincrona rispetto al resto
 del programma del gestore del segnale. Questo consente di risolvere i problemi
@@ -1956,9 +2005,9 @@ Per risolvere questo problema nello sviluppo del kernel si è pensato di
 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à
-  specifica di Linux, non presente in altri sistemi unix-like, e non prevista
-  da nessuno standard, per cui va evitata se si ha a cuore la portabilità.}
+opportuni file descriptor. Ovviamente si tratta di una funzionalità specifica
+di Linux, non presente in altri sistemi unix-like, e non prevista da nessuno
+standard, per cui va evitata se si ha a cuore la portabilità.
 
 In sostanza, come per \func{sigwait}, si può disabilitare l'esecuzione di un
 gestore in occasione dell'arrivo di un segnale, e rilevarne l'avvenuta
@@ -1970,10 +2019,10 @@ stesso modo di quelli associati a file o socket, per cui alla fine si potrà
 attendere in contemporanea sia l'arrivo del segnale che la disponibilità di
 accesso ai dati relativi a questi ultimi.
 
-La funzione che permette di abilitare la ricezione dei segnali tramite file
-descriptor è \funcd{signalfd},\footnote{in realtà quella riportata è
-  l'interfaccia alla funzione fornita dalle \acr{glibc}, esistono infatti due
-  versioni diverse della \textit{system call}; una prima versione,
+La funzione di sistema che permette di abilitare la ricezione dei segnali
+tramite file descriptor è \funcd{signalfd},\footnote{in realtà quella
+  riportata è l'interfaccia alla funzione fornita dalle \acr{glibc}, esistono
+  infatti due versioni diverse della \textit{system call}; una prima versione,
   \func{signalfd}, introdotta nel kernel 2.6.22 e disponibile con le
   \acr{glibc} 2.8 che non supporta l'argomento \texttt{flags}, ed una seconda
   versione, \funcm{signalfd4}, introdotta con il kernel 2.6.27 e che è quella
@@ -1981,27 +2030,30 @@ descriptor è \funcd{signalfd},\footnote{in realtà quella riportata è
   argomento aggiuntivo \code{size\_t sizemask} che indica la dimensione della
   \index{maschera~dei~segnali} maschera dei segnali, il cui valore viene
   impostato automaticamente dalle \acr{glibc}.}  il cui prototipo è:
-\begin{prototype}{sys/signalfd.h} 
-  {int signalfd(int fd, const sigset\_t *mask, int flags)}
 
-  Crea o modifica un file descriptor per la ricezione dei segnali. 
+\begin{funcproto}{
+\fhead{sys/signalfd.h}
+\fdecl{int signalfd(int fd, const sigset\_t *mask, int flags)}
 
-  \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:
+\fdesc{Crea o modifica un file descriptor per la ricezione dei segnali.}
+}
+
+{La funzione ritorna un numero di file descriptor in caso di successo e $-1$
+  per un errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
   \item[\errcode{EBADF}] il valore \param{fd} non indica un file descriptor.
   \item[\errcode{EINVAL}] il file descriptor \param{fd} non è stato ottenuto
     con \func{signalfd} o il valore di \param{flags} non è valido.
-  \item[\errcode{ENOMEM}] non c'è memoria sufficiente per creare un nuovo file
-    descriptor di \func{signalfd}.
   \item[\errcode{ENODEV}] il kernel non può montare internamente il
     dispositivo per la gestione anonima degli \itindex{inode} \textit{inode}
     associati al file descriptor.
+  \item[\errcode{ENOMEM}] non c'è memoria sufficiente per creare un nuovo file
+    descriptor di \func{signalfd}.
   \end{errlist}
-  ed inoltre \errval{EMFILE} e \errval{ENFILE}.  
-}
-\end{prototype}
+  ed inoltre \errval{EMFILE} e \errval{ENFILE} nel loro significato generico.
+  
+}  
+\end{funcproto}
 
 La funzione consente di creare o modificare le caratteristiche di un file
 descriptor speciale su cui ricevere le notifiche della ricezione di
@@ -2026,11 +2078,11 @@ loro inserimento nella maschera verrà ignorato senza generare errori.
 L'argomento \param{flags} consente di impostare direttamente in fase di
 creazione due flag per il file descriptor analoghi a quelli che si possono
 impostare con una creazione ordinaria con \func{open}, evitando una
-impostazione successiva con \func{fcntl}.\footnote{questo è un argomento
-  aggiuntivo, introdotto con la versione fornita a partire dal kernel 2.6.27,
-  per kernel precedenti il valore deve essere nullo.} L'argomento deve essere
-specificato come maschera binaria dei valori riportati in
-tab.~\ref{tab:signalfd_flags}.
+impostazione successiva con \func{fcntl}.\footnote{si ricordi che questo è un
+  argomento aggiuntivo, introdotto con la versione fornita a partire dal
+  kernel 2.6.27, per kernel precedenti il valore deve essere nullo.}
+L'argomento deve essere specificato come maschera binaria dei valori riportati
+in tab.~\ref{tab:signalfd_flags}.
 
 \begin{table}[htb]
   \centering
@@ -2057,9 +2109,10 @@ ordinaria dei segnali indicati da \param{mask}; questa, se si vuole effettuare
 la ricezione tramite il file descriptor, dovrà essere disabilitata
 esplicitamente bloccando gli stessi segnali con \func{sigprocmask}, altrimenti
 verranno comunque eseguite le azioni di default (o un eventuale gestore
-installato in precedenza).\footnote{il blocco non ha invece nessun effetto sul
-  file descriptor restituito da \func{signalfd}, dal quale sarà possibile
-  pertanto ricevere qualunque segnale, anche se questo risultasse bloccato.}
+installato in precedenza). Il blocco non ha invece nessun effetto sul file
+descriptor restituito da \func{signalfd}, dal quale sarà possibile pertanto
+ricevere qualunque segnale, anche se questo risultasse bloccato.
+
 Si tenga presente inoltre che la lettura di una struttura
 \struct{signalfd\_siginfo} relativa ad un segnale pendente è equivalente alla
 esecuzione di un gestore, vale a dire che una volta letta il segnale non sarà
@@ -2078,12 +2131,12 @@ diversi. Inoltre è anche possibile tenere sotto osservazione lo stesso segnale
 con più file descriptor, anche se la pratica è sconsigliata; in tal caso la
 ricezione del segnale potrà essere effettuata con una lettura da uno qualunque
 dei file descriptor a cui è associato, ma questa potrà essere eseguita
-soltanto una volta.\footnote{questo significa che tutti i file descriptor su
-  cui è presente lo stesso segnale risulteranno pronti in lettura per le
-  funzioni di \textit{I/O multiplexing}, ma una volta eseguita la lettura su
-  uno di essi il segnale sarà considerato ricevuto ed i relativi dati non
-  saranno più disponibili sugli altri file descriptor, che (a meno di una
-  ulteriore occorrenza del segnale nel frattempo) di non saranno più pronti.}
+soltanto una volta. Questo significa che tutti i file descriptor su cui è
+presente lo stesso segnale risulteranno pronti in lettura per le funzioni di
+\textit{I/O multiplexing}, ma una volta eseguita la lettura su uno di essi il
+segnale sarà considerato ricevuto ed i relativi dati non saranno più
+disponibili sugli altri file descriptor, che (a meno di una ulteriore
+occorrenza del segnale nel frattempo) di non saranno più pronti.
 
 Quando il file descriptor per la ricezione dei segnali non serve più potrà
 essere chiuso con \func{close} liberando tutte le risorse da esso allocate. In
@@ -2120,7 +2173,7 @@ successivo con \func{fcntl}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{0.90\textwidth}
     \includestruct{listati/signalfd_siginfo.h}
   \end{minipage} 
   \normalsize 
@@ -2139,6 +2192,17 @@ dimensione maggiore potranno essere letti in unica soluzione i dati relativi
 ad eventuali più segnali pendenti, fino al numero massimo di strutture
 \struct{signalfd\_siginfo} che possono rientrare nel buffer.
 
+\begin{figure}[!htb]
+  \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 contenuto di \struct{signalfd\_siginfo} ricalca da vicino quella della
 analoga struttura \struct{siginfo\_t} (illustrata in
 fig.~\ref{fig:sig_siginfo_t}) usata dall'interfaccia ordinaria dei segnali, e
@@ -2158,43 +2222,32 @@ codice completo si trova al solito nei sorgenti allegati alla guida (nel file
 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
+(\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 creazione di un file descriptor
+Il primo passo (\texttt{\small 19-20}) è la creazione 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})
+file descriptor. Per questo prima li si inseriscono (\texttt{\small 22-25})
 in una \index{maschera~dei~segnali} 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
+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
+\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
+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]
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/FifoReporter-main.c}
@@ -2205,118 +2258,117 @@ segnali.
 \end{figure}
 
 Una volta completata l'inizializzazione verrà eseguito indefinitamente il
-ciclo principale del programma (\texttt{\small 2--45}) che si è riportato in
+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 \signal{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.}
+ciclo prevede che si attenda (\texttt{\small 2-3}) la presenza di un file
+descriptor pronto in lettura con \func{epoll\_wait} (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
+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}.}
+del file descriptor riconosciuto come pronto, 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
+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 \struct{signalfd\_siginfo} alla volta, eseguendo la lettura
-all'interno di un ciclo (\texttt{\small 8--24}) che prosegue fintanto che vi
+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
+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.}
+\errcode{EAGAIN} per via dell'esaurimento dei dati. Si ricordi infatti 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 \struct{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 è
+(\texttt{\small 19-20}) il nome del segnale ottenuto all'interno della
+struttura \struct{signalfd\_siginfo} letta in \var{siginf} ed il \textit{pid}
+del processo da cui lo ha ricevuto;\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à.} inoltre
+(\texttt{\small 21-24}) si controllerà anche se il segnale ricevuto è
 \signal{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
+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
+letture in un ciclo (\texttt{\small 28-39}) ripetendole fin tanto che la
 funzione \func{read} non restituisce 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
+(\texttt{\small 29-35}). 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 
+\begin{Console}
+piccardi@hain:~/gapil/sources$ \textbf{./a.out} 
 FifoReporter starting, pid 4568
-\end{Verbatim}
+\end{Console}
 %$
 e scrivendo qualcosa sull'altro terminale con:
-\begin{Verbatim}
-root@hain:~# echo prova > /tmp/reporter.fifo  
-\end{Verbatim}
+\begin{Console}
+root@hain:~# \textbf{echo prova > /tmp/reporter.fifo}  
+\end{Console}
 si otterrà:
-\begin{Verbatim}
+\begin{Console}
 Message from fifo:
 prova
 end message
-\end{Verbatim}
+\end{Console}
 mentre inviando un segnale:
-\begin{Verbatim}
-root@hain:~# kill 4568
-\end{Verbatim}
+\begin{Console}
+root@hain:~# \textbf{kill 4568}
+\end{Console}
 si avrà:
-\begin{Verbatim}
+\begin{Console}
 Signal received:
 Got SIGTERM       
 From pid 3361
-\end{Verbatim}
+\end{Console}
 ed infine premendo \texttt{C-\bslash} sul terminale in cui è in esecuzione si
 vedrà:
-\begin{Verbatim}
-^\Signal received:
+\begin{Console}
+^\\Signal received:
 Got SIGQUIT       
 From pid 0
-\end{Verbatim}
+\end{Console}
 e si potrà far uscire il programma con \texttt{C-c} ottenendo:
-\begin{Verbatim}
+\begin{Console}
 ^CSignal received:
 Got SIGINT        
 From pid 0
 SIGINT means exit
-\end{Verbatim}
-
+\end{Console}
 
 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
@@ -2325,10 +2377,10 @@ 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 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 consente di fare tutto con una sola
-  \textit{system call}.}
+timer. 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 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
@@ -2338,30 +2390,33 @@ abbiamo già illustrato in sez.~\ref{sec:sig_timer_adv}.\footnote{questa
   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)}
+  supportata e non deve essere usata.} La prima funzione di sistema prevista,
+quella che consente di creare un timer, è \funcd{timerfd\_create}, il cui
+prototipo è:
 
-  Crea un timer associato ad un file descriptor per la notifica. 
+\begin{funcproto}{
+\fhead{sys/timerfd.h}
+\fdecl{int timerfd\_create(int clockid, int flags)}
 
-  \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:
+\fdesc{Crea un timer associato ad un file descriptor per la notifica.}
+}
+
+{La funzione ritorna un numero di file descriptor in caso di successo e $-1$
+  per un errore, nel qual caso \var{errno} assumerà uno dei valori:
   \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
     precedenti il 2.6.27.
-  \item[\errcode{ENOMEM}] non c'è memoria sufficiente per creare un nuovo file
-    descriptor di \func{signalfd}.
   \item[\errcode{ENODEV}] il kernel non può montare internamente il
     dispositivo per la gestione anonima degli \itindex{inode} \textit{inode}
     associati al file descriptor.
+  \item[\errcode{ENOMEM}] non c'è memoria sufficiente per creare un nuovo file
+    descriptor di \func{signalfd}.
   \end{errlist}
-  ed inoltre \errval{EMFILE} e \errval{ENFILE}.  
-}
-\end{prototype}
+  ed inoltre \errval{EMFILE} e \errval{ENFILE} nel loro significato generico.
+}  
+\end{funcproto}
 
 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
@@ -2399,41 +2454,43 @@ tab.~\ref{tab:timerfd_flags}.
 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
+unix-like, in particolare resta aperto attraverso una \func{exec} (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}.}
+timer impostati con le funzioni ordinarie. 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 è
+periodicità di ripetizione, per farlo si usa una funzione di sistema 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. 
+\begin{funcproto}{
+\fhead{sys/timerfd.h}
+\fdecl{int timerfd\_settime(int fd, int flags,
+                           const struct itimerspec *new\_value,\\
+\phantom{int timerfd\_settime(}struct itimerspec *old\_value)}
 
-  \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:
+\fdesc{Crea un timer associato ad un file descriptor per la notifica.}
+}
+
+{La funzione ritorna un numero di file descriptor in caso di successo e $-1$
+  per un 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{EFAULT}] o \param{new\_value} o \param{old\_value} non sono
+    puntatori validi.
   \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}
+}  
+\end{funcproto}
 
 In questo caso occorre indicare su quale timer si intende operare specificando
 come primo argomento il file descriptor ad esso associato, che deve essere
@@ -2456,14 +2513,16 @@ valori possibili rispettivamente soltanto $0$ e
 
 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. 
+\begin{funcproto}{
+\fhead{sys/timerfd.h}
+\fdecl{int timerfd\_gettime(int fd, struct itimerspec *curr\_value)}
 
-  \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:
+\fdesc{Crea un timer associato ad un file descriptor per la notifica.}
+}
+
+{La funzione ritorna un numero di file descriptor in caso di successo e $-1$
+  per un 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. 
@@ -2471,24 +2530,18 @@ che è l'analoga di \func{timer\_gettime}, il suo prototipo è:
     con \func{timerfd\_create}.
   \item[\errcode{EFAULT}] o \param{curr\_value} non è un puntatore valido.
   \end{errlist}
-}
-\end{prototype}
-
-
-
-
+ed inoltre      nel suo significato generico.
+  
+}  
+\end{funcproto}
 
 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}, 
-
-
+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 
@@ -3238,17 +3291,17 @@ funzioni di ausilio è riportato in fig.~\ref{fig:inotify_monitor_example}.
 \end{figure}
 
 Una volta completata la scansione delle opzioni il corpo principale del
-programma inizia controllando (\texttt{\small 11--15}) che sia rimasto almeno
+programma inizia controllando (\texttt{\small 11-15}) che sia rimasto almeno
 un argomento che indichi quale file o directory mettere sotto osservazione (e
 qualora questo non avvenga esce stampando la pagina di aiuto); dopo di che
-passa (\texttt{\small 16--20}) all'inizializzazione di \textit{inotify}
+passa (\texttt{\small 16-20}) all'inizializzazione di \textit{inotify}
 ottenendo con \func{inotify\_init} il relativo file descriptor (oppure usce in
 caso di errore).
 
-Il passo successivo è aggiungere (\texttt{\small 21--30}) alla coda di
+Il passo successivo è aggiungere (\texttt{\small 21-30}) alla coda di
 notifica gli opportuni osservatori per ciascuno dei file o directory indicati
 all'invocazione del comando; questo viene fatto eseguendo un ciclo
-(\texttt{\small 22--29}) fintanto che la variabile \var{i}, inizializzata a
+(\texttt{\small 22-29}) fintanto che la variabile \var{i}, inizializzata a
 zero (\texttt{\small 21}) all'inizio del ciclo, è minore del numero totale di
 argomenti rimasti. All'interno del ciclo si invoca (\texttt{\small 23})
 \func{inotify\_add\_watch} per ciascuno degli argomenti, usando la maschera
@@ -3257,7 +3310,7 @@ nella scansione delle opzioni), in caso di errore si esce dal programma
 altrimenti si incrementa l'indice (\texttt{\small 29}).
 
 Completa l'inizializzazione di \textit{inotify} inizia il ciclo principale
-(\texttt{\small 32--56}) del programma, nel quale si resta in attesa degli
+(\texttt{\small 32-56}) del programma, nel quale si resta in attesa degli
 eventi che si intendono osservare. Questo viene fatto eseguendo all'inizio del
 ciclo (\texttt{\small 33}) una \func{read} che si bloccherà fintanto che non
 si saranno verificati eventi. 
@@ -3268,13 +3321,13 @@ dimensioni adeguate, inizializzato in (\texttt{\small 7}) ad un valore di
 approssimativamente 512 eventi.\footnote{si ricordi che la quantità di dati
   restituita da \textit{inotify} è variabile a causa della diversa lunghezza
   del nome del file restituito insieme a \struct{inotify\_event}.} In caso di
-errore di lettura (\texttt{\small 35--40}) il programma esce con un messaggio
-di errore (\texttt{\small 37--39}), a meno che non si tratti di una
+errore di lettura (\texttt{\small 35-40}) il programma esce con un messaggio
+di errore (\texttt{\small 37-39}), a meno che non si tratti di una
 interruzione della \textit{system call}, nel qual caso (\texttt{\small 36}) si
 ripete la lettura.
 
 Se la lettura è andata a buon fine invece si esegue un ciclo (\texttt{\small
-  43--52}) per leggere tutti gli eventi restituiti, al solito si inizializza
+  43-52}) per leggere tutti gli eventi restituiti, al solito si inizializza
 l'indice \var{i} a zero (\texttt{\small 42}) e si ripetono le operazioni
 (\texttt{\small 43}) fintanto che esso non supera il numero di byte restituiti
 in lettura. Per ciascun evento all'interno del ciclo si assegna\footnote{si
@@ -3287,7 +3340,7 @@ comando sfruttando il fatto che i \textit{watch descriptor} vengono assegnati
 in ordine progressivo crescente a partire da 1.
 
 Qualora sia presente il riferimento ad un nome di file associato all'evento lo
-si stampa (\texttt{\small 47--49}); si noti come in questo caso si sia
+si stampa (\texttt{\small 47-49}); si noti come in questo caso si sia
 utilizzato il valore del campo \var{event->len} e non al fatto che
 \var{event->name} riporti o meno un puntatore nullo.\footnote{l'interfaccia
   infatti, qualora il nome non sia presente, non avvalora il campo
@@ -3304,15 +3357,16 @@ aggiornare l'indice \var{i} per farlo puntare all'evento successivo.
 Se adesso usiamo il programma per mettere sotto osservazione una directory, e
 da un altro terminale eseguiamo il comando \texttt{ls} otterremo qualcosa del
 tipo di:
-\begin{verbatim}
-piccardi@gethen:~/gapil/sources$ ./inotify_monitor -a /home/piccardi/gapil/
+\begin{Console}
+piccardi@gethen:~/gapil/sources$ \textbf{./inotify_monitor -a /home/piccardi/gapil/}
 Watch descriptor 1
 Observed event on /home/piccardi/gapil/
 IN_OPEN, 
 Watch descriptor 1
 Observed event on /home/piccardi/gapil/
 IN_CLOSE_NOWRITE, 
-\end{verbatim}
+\end{Console}
+%$
 
 I lettori più accorti si saranno resi conto che nel ciclo di lettura degli
 eventi appena illustrato non viene trattato il caso particolare in cui la
@@ -4921,10 +4975,10 @@ fig.~\ref{fig:splicecp_data_flux}.
 \end{figure}
 
 Una volta trattate le opzioni il programma verifica che restino
-(\texttt{\small 13--16}) i due argomenti che indicano il file sorgente ed il
+(\texttt{\small 13-16}) i due argomenti che indicano il file sorgente ed il
 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.
+(\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}[!htbp]
   \footnotesize \centering
@@ -4937,8 +4991,8 @@ infine (\texttt{\small 28--31}) la \textit{pipe} che verrà usata come buffer.
   \label{fig:splice_example}
 \end{figure}
 
-Il ciclo principale (\texttt{\small 33--58}) inizia con la lettura dal file
-sorgente tramite la prima \func{splice} (\texttt{\small 34--35}), in questo
+Il ciclo principale (\texttt{\small 33-58}) inizia con la lettura dal file
+sorgente tramite la prima \func{splice} (\texttt{\small 34-35}), in questo
 caso si è usato come primo argomento il file descriptor del file sorgente e
 come terzo quello del capo in scrittura della \textit{pipe} (il funzionamento
 delle \textit{pipe} e l'uso della coppia di file descriptor ad esse associati
@@ -4953,13 +5007,13 @@ valore di uscita in \var{nread} che indica quanti byte sono stati letti, se
 detto valore è nullo (\texttt{\small 36}) questo significa che si è giunti
 alla fine del file sorgente e pertanto l'operazione di copia è conclusa e si
 può uscire dal ciclo arrivando alla conclusione del programma (\texttt{\small
-  59}). In caso di valore negativo (\texttt{\small 37--44}) c'è stato un
+  59}). In caso di valore negativo (\texttt{\small 37-44}) c'è stato un
 errore ed allora si ripete la lettura (\texttt{\small 36}) se questo è dovuto
 ad una interruzione, o altrimenti si esce con un messaggio di errore
-(\texttt{\small 41--43}).
+(\texttt{\small 41-43}).
 
 Una volta completata con successo la lettura si avvia il ciclo di scrittura
-(\texttt{\small 45--57}); questo inizia (\texttt{\small 46--47}) con la
+(\texttt{\small 45-57}); questo inizia (\texttt{\small 46-47}) con la
 seconda \func{splice} che cerca di scrivere gli \var{nread} byte letti, si
 noti come in questo caso il primo argomento faccia di nuovo riferimento alla
 \textit{pipe} (in questo caso si usa il capo in lettura, per i dettagli si
@@ -4969,7 +5023,7 @@ del file di destinazione.
 Di nuovo si controlla il numero di byte effettivamente scritti restituito in
 \var{nwrite} e in caso di errore al solito si ripete la scrittura se questo è
 dovuto a una interruzione o si esce con un messaggio negli altri casi
-(\texttt{\small 48--55}). Infine si chiude il ciclo di scrittura sottraendo
+(\texttt{\small 48-55}). Infine si chiude il ciclo di scrittura sottraendo
 (\texttt{\small 57}) il numero di byte scritti a quelli di cui è richiesta la
 scrittura,\footnote{in questa parte del ciclo \var{nread}, il cui valore
   iniziale è dato dai byte letti dalla precedente chiamata a \func{splice},
@@ -5110,25 +5164,25 @@ allegati alla guida.
   \label{fig:tee_example}
 \end{figure}
 
-La prima parte del programma (\texttt{\small 10--35}) si cura semplicemente di
-controllare (\texttt{\small 11--14}) che sia stato fornito almeno un argomento
-(il nome del file su cui scrivere), di aprirlo ({\small 15--19}) e che sia lo
-standard input (\texttt{\small 20--27}) che lo standard output (\texttt{\small
-  28--35}) corrispondano ad una \textit{pipe}.
+La prima parte del programma (\texttt{\small 10-35}) si cura semplicemente di
+controllare (\texttt{\small 11-14}) che sia stato fornito almeno un argomento
+(il nome del file su cui scrivere), di aprirlo ({\small 15-19}) e che sia lo
+standard input (\texttt{\small 20-27}) che lo standard output (\texttt{\small
+  28-35}) corrispondano ad una \textit{pipe}.
 
-Il ciclo principale (\texttt{\small 37--58}) inizia con la chiamata a
+Il ciclo principale (\texttt{\small 37-58}) inizia con la chiamata a
 \func{tee} che duplica il contenuto dello standard input sullo standard output
 (\texttt{\small 39}), questa parte è del tutto analoga ad una lettura ed
 infatti come nell'esempio di fig.~\ref{fig:splice_example} si controlla il
 valore di ritorno della funzione in \var{len}; se questo è nullo significa che
 non ci sono più dati da leggere e si chiude il ciclo (\texttt{\small 40}), se
 è negativo c'è stato un errore, ed allora si ripete la chiamata se questo è
-dovuto ad una interruzione (\texttt{\small 42--44}) o si stampa un messaggio
-di errore e si esce negli altri casi (\texttt{\small 44--47}).
+dovuto ad una interruzione (\texttt{\small 42-44}) o si stampa un messaggio
+di errore e si esce negli altri casi (\texttt{\small 44-47}).
 
 Una volta completata la copia dei dati sullo standard output si possono
 estrarre dalla standard input e scrivere sul file, di nuovo su usa un ciclo di
-scrittura (\texttt{\small 50--58}) in cui si ripete una chiamata a
+scrittura (\texttt{\small 50-58}) in cui si ripete una chiamata a
 \func{splice} (\texttt{\small 51}) fintanto che non si sono scritti tutti i
 \var{len} byte copiati in precedenza con \func{tee} (il funzionamento è
 identico all'analogo ciclo di scrittura del precedente esempio di