Applicate correzioni e nuova figura inviate da Alessio Frusciante.
[gapil.git] / fileadv.tex
index 9bd8e161bb3e2a0735f92d5dc13305d03fb4f154..6f87c7bb4132654252dd3581314b1a7484c4b2db 100644 (file)
@@ -1,6 +1,6 @@
 %% fileadv.tex
 %%
-%% Copyright (C) 2000-2010 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2011 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
@@ -10,7 +10,6 @@
 %%
 \chapter{La gestione avanzata dei file}
 \label{cha:file_advanced}
-
 In questo capitolo affronteremo le tematiche relative alla gestione avanzata
 dei file. Inizieremo con la trattazione delle problematiche del \textit{file
   locking} e poi prenderemo in esame le varie funzionalità avanzate che
@@ -1474,7 +1473,7 @@ vengano notificati solo i file descriptor che hanno subito una transizione da
 \textit{edge triggered} nel caso del precedente esempio il file descriptor
 diventato pronto da cui si sono letti solo 1000 byte non verrà nuovamente
 notificato come pronto, nonostante siano ancora disponibili in lettura 1000
-byte. Solo una volta che si saranno esauriti tutti i byte disponibili, e che
+byte. Solo una volta che si saranno esauriti tutti i dati disponibili, e che
 il file descriptor sia tornato non essere pronto, si potrà ricevere una
 ulteriore notifica qualora ritornasse pronto.
 
@@ -1494,36 +1493,59 @@ 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 una apposita \textit{system call}.  Il
-primo passo per usare l'interfaccia di \textit{epoll} è pertanto quello di
-chiamare la funzione \funcd{epoll\_create}, il cui prototipo è:
-\begin{prototype}{sys/epoll.h}
-  {int epoll\_create(int size)}
+  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}
+
+  \funcdecl{int epoll\_create(int size)}
+  \funcdecl{int epoll\_create1(int flags)}
   
   Apre un file descriptor per \textit{epoll}.
   
-  \bodydesc{La funzione restituisce un file descriptor in caso di successo, o
-    $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \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{errlist}
   \item[\errcode{EINVAL}] si è specificato un valore di \param{size} non
-    positivo.
+    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
+    \procfile{/proc/sys/fs/epoll/max\_user\_instances}.
   \item[\errcode{ENOMEM}] non c'è sufficiente memoria nel kernel per creare
     l'istanza.
   \end{errlist}
 }
-\end{prototype}
+\end{functions}
 
-La funzione restituisce 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; l'argomento \param{size} serve a dare
-l'indicazione del numero di file descriptor che si vorranno tenere sotto
-controllo, ma costituisce solo un suggerimento per semplificare l'allocazione
-di risorse sufficienti, non un valore massimo.
+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 tab.~\ref{tab:file_open_flags}), 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
@@ -1549,6 +1571,9 @@ controllare, per questo si deve usare la seconda funzione dell'interfaccia,
   \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
+    \procfile{/proc/sys/fs/epoll/max\_user\_watches}.
   \end{errlist}
 }
 \end{prototype}
@@ -1597,8 +1622,10 @@ di tipo \struct{epoll\_event}, ed ha significato solo con le operazioni
 indicare quale tipo di evento relativo ad \param{fd} si vuole che sia tenuto
 sotto controllo.  L'argomento viene ignorato con l'operazione
 \const{EPOLL\_CTL\_DEL}.\footnote{fino al kernel 2.6.9 era comunque richiesto
-  che questo fosse un puntatore valido, anche se poi veniva ignorato, a
-  partire dal 2.6.9 si può specificare anche un valore \texttt{NULL}.}
+  che questo fosse un puntatore valido, anche se poi veniva ignorato; a
+  partire dal 2.6.9 si può specificare anche un valore \texttt{NULL} ma se si
+  vuole mantenere la compatibilità con le versioni precedenti occorre usare un
+  puntatore valido.}
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1621,10 +1648,14 @@ definizione 
 Il primo campo, \var{events}, è una maschera binaria in cui ciascun bit
 corrisponde o ad un tipo di evento, o una modalità di notifica; detto campo
 deve essere specificato come OR aritmetico delle costanti riportate in
-tab.~\ref{tab:epoll_events}. Il secondo campo, \var{data}, serve ad indicare a
-quale file descriptor si intende fare riferimento, ed in astratto può
-contenere un valore qualsiasi che permetta di identificarlo, di norma comunque
-si usa come valore lo stesso \param{fd}.
+tab.~\ref{tab:epoll_events}. Il secondo campo, \var{data}, è una \ctyp{union}
+che serve a identificare il file descriptor a cui si intende fare riferimento,
+ed in astratto può contenere un valore qualsiasi (specificabile in diverse
+forme) che ne permetta una indicazione univoca. Il modo più comune di usarlo
+però è quello in cui si specifica il terzo argomento di \func{epoll\_ctl}
+nella forma \var{event.data.fd}, assegnando come valore di questo campo lo
+stesso valore dell'argomento \param{fd}, cosa che permette una immediata
+identificazione del file descriptor.
 
 \begin{table}[htb]
   \centering
@@ -1641,7 +1672,8 @@ si usa come valore lo stesso \param{fd}.
     \const{EPOLLRDHUP}  & L'altro capo di un socket di tipo
                           \const{SOCK\_STREAM} (vedi sez.~\ref{sec:sock_type})
                           ha chiuso la connessione o il capo in scrittura
-                          della stessa (vedi sez.~\ref{sec:TCP_shutdown}).\\
+                          della stessa (vedi
+                          sez.~\ref{sec:TCP_shutdown}).\footnotemark\\
     \const{EPOLLPRI}    & Ci sono \itindex{out-of-band} dati urgenti
                           disponibili in lettura (analogo di
                           \const{POLLPRI}); questa condizione viene comunque
@@ -1651,7 +1683,9 @@ si usa come valore lo stesso \param{fd}.
                           (analogo di \const{POLLERR}); questa condizione
                           viene comunque riportata in uscita, e non è
                           necessaria impostarla in ingresso.\\
-    \const{EPOLLHUP}    & Si è verificata una condizione di hung-up.\\
+    \const{EPOLLHUP}    & Si è verificata una condizione di hung-up; questa
+                          condizione viene comunque riportata in uscita, e non
+                          è necessaria impostarla in ingresso.\\
     \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
@@ -1663,7 +1697,12 @@ si usa come valore lo stesso \param{fd}.
   \label{tab:epoll_events}
 \end{table}
 
-\footnotetext{questa modalità è disponibile solo a partire dal kernel 2.6.2.}
+\footnotetext{questa modalità è disponibile solo a partire dal kernel 2.6.17,
+  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.}
 
 Le modalità di utilizzo di \textit{epoll} prevedono che si definisca qual'è
 l'insieme dei file descriptor da tenere sotto controllo tramite un certo
@@ -1781,9 +1820,10 @@ restituiti meno dati di quelli richiesti.
 
 Come già per \func{select} e \func{poll} anche per l'interfaccia di
 \textit{epoll} si pone il problema di gestire l'attesa di segnali e di dati
-contemporaneamente, per far questo di nuovo è necessaria una variante della
-funzione di attesa che consenta di reimpostare all'uscita una maschera di
-segnali, analoga alle precedenti estensioni \func{pselect} e \func{ppoll} di
+contemporaneamente per le osservazioni fatte in sez.~\ref{sec:file_select},
+per fare questo di nuovo è necessaria una variante della funzione di attesa
+che consenta di reimpostare all'uscita una 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 introdotta a partire dal
   kernel 2.6.19, ed è come tutta l'interfaccia di \textit{epoll}, specifica di
@@ -1825,9 +1865,10 @@ programma che utilizza questa interfaccia in sez.~\ref{sec:TCP_serv_epoll}.
 Abbiamo visto in sez.~\ref{sec:file_select} come il meccanismo classico delle
 notifiche di eventi tramite i segnali, presente da sempre nei sistemi
 unix-like, porti a notevoli problemi nell'interazione con le funzioni per
-l'I/O multiplexing, tanto che per evitare possibili \itindex{race~condition}
-\textit{race condition} sono state introdotte estensioni dello standard POSIX e
-funzioni apposite come \func{pselect}, \func{ppoll} e \funcd{epoll\_pwait}.
+l'\textit{I/O multiplexing}, tanto che per evitare possibili
+\itindex{race~condition} \textit{race condition} sono state introdotte
+estensioni dello standard POSIX e funzioni apposite come \func{pselect},
+\func{ppoll} e \funcd{epoll\_pwait}.
 
 Benché i segnali siano il meccanismo più usato per effettuare notifiche ai
 processi, la loro interfaccia di programmazione, che comporta l'esecuzione di
@@ -1857,10 +1898,10 @@ Abbiamo visto per
 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 di atomicità nella gestione degli eventi associati ai segnali, avendo
-tutto il controllo nel flusso principale del programma, ottenendo così una
-gestione simile a quella dell'I/O multiplexing, ma non risolve i problemi
+del programma del gestore del segnale. Questo consente di risolvere i problemi
+di atomicità nella gestione degli eventi associati ai segnali, avendo tutto il
+controllo nel flusso principale del programma, ottenendo così una gestione
+simile a quella dell'\textit{I/O multiplexing}, ma non risolve i problemi
 delle interazioni con quest'ultimo, perché o si aspetta la ricezione di un
 segnale o si aspetta che un file descriptor sia accessibile e nessuna delle
 rispettive funzioni consente di fare contemporaneamente entrambe le cose.
@@ -1877,25 +1918,27 @@ In sostanza, come per \func{sigwait}, si pu
 gestore in occasione dell'arrivo di un segnale, e rilevarne l'avvenuta
 ricezione leggendone la notifica tramite l'uso di uno speciale file
 descriptor. Trattandosi di un file descriptor questo potrà essere tenuto sotto
-osservazione con le ordinarie funzioni dell'I/O multiplexing (vale a dire con
-le solite \func{select}, \func{poll} e \funcd{epoll\_wait}) allo 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.
+osservazione con le ordinarie funzioni dell'\textit{I/O multiplexing} (vale a
+dire con le solite \func{select}, \func{poll} e \funcd{epoll\_wait}) allo
+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 è la
-  interfacia alla funzione fornita dalle \acr{glibc}, esistono in realtà due
-  versioni diverse della \textit{system call}, la prima versione,
+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, ed una seconda versione,
-  \func{signalfd4}, che prende argomenti aggiuntivi, introdotta con il kernel
-  2.6.27 che è quella che viene sempre usata a partire dalle \acr{glibc} 2.9.}
-il cui prototipo è:
+  \acr{glibc} 2.8 che non supporta l'argomento \texttt{flags}, ed una seconda
+  versione, \func{signalfd4}, introdotta con il kernel 2.6.27 e che è quella
+  che viene sempre usata a partire dalle \acr{glibc} 2.9, che prende un
+  argomento aggiuntivo \code{size\_t sizemask} che indica la dimensione della
+  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 pet la ricezione dei segnali. 
+  Crea o modifica un file descriptor per la ricezione dei segnali. 
 
   \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
@@ -1904,7 +1947,7 @@ il cui prototipo 
   \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{ENOMEN}] non c'è memoria sufficiente per creare un nuovo file
+  \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 inode associati al file
@@ -1927,19 +1970,21 @@ con \param{fd}, in caso di errore invece verr
 L'elenco dei segnali che si vogliono gestire con \func{signalfd} deve essere
 specificato tramite l'argomento \param{mask}. Questo deve essere passato come
 puntatore ad una maschera di segnali creata con l'uso delle apposite macro già
-illustrate in sez.~\ref{sec:sig_sigset}; la maschera deve indicare su quali
+illustrate in sez.~\ref{sec:sig_sigset}. La maschera deve indicare su quali
 segnali si intende operare con \func{signalfd}; l'elenco può essere modificato
 con una successiva chiamata a \func{signalfd}. Dato che \const{SIGKILL} e
 \const{SIGSTOP} non possono essere intercettati (e non prevedono neanche la
-possibilità di un gestore) un loro inserimento nella maschera verrà ignorato,
-senza generare errori.
+possibilità di un gestore) un 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.}
+  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
@@ -1961,21 +2006,176 @@ impostazione successiva con \func{fcntl}.\footnote{questo 
   \label{tab:signalfd_flags}
 \end{table}
 
+Si tenga presente che la chiamata a \func{signalfd} non disabilita la gestione
+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.}
+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à
+più pendente e non potrà essere ricevuto, qualora si ripristino le normali
+condizioni di gestione, né da un gestore né dalla funzione \func{sigwaitinfo}.
+
+Come anticipato, essendo questo lo scopo principale della nuova interfaccia,
+il file descriptor può essere tenuto sotto osservazione tramite le funzioni
+dell'\textit{I/O multiplexing} (vale a dire con le solite \func{select},
+\func{poll} e \funcd{epoll\_wait}), e risulterà accessibile in lettura quando
+uno o più dei segnali indicati tramite \param{mask} sarà pendente.
+
+La funzione può essere chiamata più volte dallo stesso processo, consentendo
+così di tenere sotto osservazione segnali diversi tramite file descriptor
+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.}
+
+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
+tal caso qualora vi fossero segnali pendenti questi resteranno tali, e
+potranno essere ricevuti normalmente una volta che si rimuova il blocco
+imposto con \func{sigprocmask}.
+
+Oltre che con le funzioni dell'\textit{I/O multiplexing} l'uso del file
+descriptor restituito da \func{signalfd} cerca di seguire la semantica di un
+sistema unix-like anche con altre \textit{system call}; in particolare esso
+resta aperto (come ogni altro file descriptor) attraverso una chiamata ad
+\func{exec}, a meno che non lo si sia creato con il flag di
+\const{SFD\_CLOEXEC} o si sia successivamente impostato il
+\textit{close-on-exec} con \func{fcntl}. Questo comportamento corrisponde
+anche alla ordinaria semantica relativa ai segnali bloccati, che restano
+pendenti attraverso una \func{exec}.
+
+Analogamente il file descriptor resta sempre disponibile attraverso una
+\func{fork} per il processo figlio, che ne riceve una copia; in tal caso però
+il figlio potrà leggere dallo stesso soltanto i dati relativi ai segnali
+ricevuti da lui stesso. Nel caso di \textit{thread} viene nuovamente seguita
+la semantica ordinaria dei segnali, che prevede che un singolo \textit{thread}
+possa ricevere dal file descriptor solo le notifiche di segnali inviati
+direttamente a lui o al processo in generale, e non quelli relativi ad altri
+\textit{thread} appartenenti allo stesso processo.
+
 L'interfaccia fornita da \func{signalfd} prevede che la ricezione dei segnali
-sia eseguita leggendo dal file descriptor restituito dalla funzione. La
-lettura fornisce nel buffer indicato come secondo argomento alla funzione
-\func{read} una o più strutture \struct{signalfd\_siginfo} a seconda della
-dimensione dello stesso e del numero di segnali pendenti. Pertanto il buffer
-deve essere almeno di dimensione pari a \code{sizeof(signalfd\_siginfo)}; se
-di dimensione maggiore potranno essere letti in unica soluzione 
-
-% TODO trattare qui eventfd, signalfd e timerfd introdotte con il 2.6.22 
+sia eseguita leggendo i dati relativi ai segnali pendenti dal file descriptor
+restituito dalla funzione con una normalissima \func{read}.  Qualora non vi
+siano segnali pendenti la \func{read} si bloccherà a meno di non aver
+impostato la modalità di I/O non bloccante sul file descriptor, o direttamente
+in fase di creazione con il flag \const{SFD\_NONBLOCK}, o in un momento
+successivo con \func{fcntl}.  
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includestruct{listati/signalfd_siginfo.h}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \structd{signalfd\_siginfo}, restituita in lettura da
+    un file descriptor creato con \func{signalfd}.}
+  \label{fig:signalfd_siginfo}
+\end{figure}
+
+I dati letti dal file descriptor vengono scritti sul buffer indicato come
+secondo argomento di \func{read} nella forma di una sequenza di una o più
+strutture \struct{signalfd\_siginfo} (la cui definizione si è riportata in
+fig.~\ref{fig:signalfd_siginfo}) a seconda sia della dimensione del buffer che
+del numero di segnali pendenti. Per questo motivo il buffer deve essere almeno
+di dimensione pari a quella di \struct{signalfd\_siginfo}, qualora sia di
+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.
+
+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
+restituisce dati simili. Come per \struct{siginfo\_t} i campi che vengono
+avvalorati dipendono dal tipo di segnale e ricalcano i valori che abbiamo già
+illustrato in sez.~\ref{sec:sig_sigaction}.\footnote{si tenga presente però
+  che per un bug i kernel fino al 2.6.25 non avvalorano correttamente i campi
+  \var{ssi\_ptr} e \var{ssi\_int} per segnali inviati con \func{sigqueue}.}
+
+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
+sez.~\ref{sec:sig_timer_adv}, la scadenza di un timer potrà essere letta da un
+file descriptor, senza dover ricorrere ad altri meccanismi di notifica come un
+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 di un segnale
+qualunque.\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.}
+
+Le funzioni di questa interfaccia riprendono da vicino quelle introdotte da
+POSIX.1-2001 illustrate sez.~\ref{sec:sig_timer_adv}. La prima funzione, che
+consente di creare un \textit{timer} è \funcd{timerfd\_create}, il cui
+prototipo è:
+\begin{prototype}{sys/timerfd.h} 
+  {int timerfd\_create(int clockid, int flags)}
+
+  Crea un timer associato ad un file descriptor per la notifica. 
+
+  \bodydesc{La funzione restituisce un numero di file descriptor in caso di
+    successo o $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno
+    dei valori:
+  \begin{errlist}
+  \item[\errcode{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 inode associati al file
+    descriptor.
+  \end{errlist}
+  ed inoltre \errval{EMFILE} e \errval{ENFILE}.  
+}
+\end{prototype}
+
+La funzione prende come primo argomento il tipo di orologio a cui il timer
+deve fare riferimento, ed i soli valori validi sono \const{CLOCK\_REALTIME},
+per indicare 
+
+
+% TODO trattare qui eventfd, timerfd introdotte con il 2.6.22 
 % timerfd è stata tolta nel 2.6.23 e rifatta per bene nel 2.6.25
 % vedi: http://lwn.net/Articles/233462/
 %       http://lwn.net/Articles/245533/
 %       http://lwn.net/Articles/267331/
 
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/FifoReporter-init.c}
+  \end{minipage} 
+  \normalsize 
+  \caption{Sezione di inizializzazione del codice del programma
+    \file{FifoReporter.c}.}
+  \label{fig:fiforeporter_code}
+\end{figure}
+
+
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/FifoReporter-main.c}
+  \end{minipage} 
+  \normalsize 
+  \caption{Ciclo principale del codice del programma \file{FifoReporter.c}.}
+  \label{fig:fiforeporter_code}
+\end{figure}
+
+
 
 \section{L'accesso \textsl{asincrono} ai file}
 \label{sec:file_asyncronous_access}
@@ -3275,7 +3475,7 @@ eseguire la mappatura in memoria di un file, 
 \end{functions}
 
 La funzione richiede di mappare in memoria la sezione del file \param{fd} a
-partire da \param{offset} per \param{lenght} byte, preferibilmente
+partire da \param{offset} per \param{length} byte, preferibilmente
 all'indirizzo \param{start}. Il valore di \param{offset} deve essere un
 multiplo della dimensione di una pagina di memoria. 
 
@@ -3436,7 +3636,7 @@ verr
 bordo della pagina successiva.
 
 In questo caso è possibile accedere a quella zona di memoria che eccede le
-dimensioni specificate da \param{lenght}, senza ottenere un \const{SIGSEGV}
+dimensioni specificate da \param{length}, senza ottenere un \const{SIGSEGV}
 poiché essa è presente nello spazio di indirizzi del processo, anche se non è
 mappata sul file. Il comportamento del sistema è quello di restituire un
 valore nullo per quanto viene letto, e di non riportare su file quanto viene
@@ -3839,9 +4039,9 @@ le opportune strategie di ottimizzazione. Il suo prototipo 
 
 La sezione di memoria sulla quale si intendono fornire le indicazioni deve
 essere indicata con l'indirizzo iniziale \param{start} e l'estensione
-\param{lenght}, il valore di \param{start} deve essere allineato,
+\param{length}, il valore di \param{start} deve essere allineato,
 mentre \param{length} deve essere un numero positivo.\footnote{la versione di
-  Linux consente anche un valore nullo per \param{lenght}, inoltre se una
+  Linux consente anche un valore nullo per \param{length}, inoltre se una
   parte dell'intervallo non è mappato in memoria l'indicazione viene comunque
   applicata alle restanti parti, anche se la funzione ritorna un errore di
   \errval{ENOMEM}.} L'indicazione viene espressa dall'argomento \param{advice}
@@ -4966,7 +5166,7 @@ livello di kernel.
 % LocalWords:  only ETXTBSY DENYWRITE ENODEV filesystem EPERM EXEC noexec table
 % LocalWords:  ENFILE lenght segment violation SIGSEGV FIXED msync munmap copy
 % LocalWords:  DoS Denial Service EXECUTABLE NORESERVE LOCKED swapping stack fs
-% LocalWords:  GROWSDOWN ANON POPULATE prefaulting SIGBUS fifo VME fork old
+% LocalWords:  GROWSDOWN ANON POPULATE prefaulting SIGBUS fifo VME fork old SFD
 % LocalWords:  exec atime ctime mtime mprotect addr EACCESS mremap address new
 % LocalWords:  long MAYMOVE realloc VMA virtual Ingo Molnar remap pages pgoff
 % LocalWords:  dall' fault cache linker prelink advisory discrectionary lock fl
@@ -4989,8 +5189,9 @@ livello di kernel.
 % LocalWords:  SEQUENTIAL NOREUSE WILLNEED DONTNEED streaming fallocate EFBIG
 % LocalWords:  POLLRDHUP half close pwait Gb madvise MADV ahead REMOVE tmpfs
 % LocalWords:  DONTFORK DOFORK shmfs preadv pwritev syscall linux loff head XFS
-% LocalWords:  MERGEABLE EOVERFLOW prealloca hole FALLOC KEEP stat fstat
-% LocalWords:  conditions sigwait
+% LocalWords:  MERGEABLE EOVERFLOW prealloca hole FALLOC KEEP stat fstat union
+% LocalWords:  conditions sigwait CLOEXEC signalfd sizemask SIGKILL SIGSTOP ssi
+% LocalWords:  sigwaitinfo FifoReporter Windows ptr sigqueue
 
 
 %%% Local Variables: