+ 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
+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}.
+
+\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
+struttura, la cui definizione è riportata in fig.~\ref{fig:file_pollfd},
+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} 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.
+
+Le costanti che definiscono i valori relativi ai bit usati nelle maschere
+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 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
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Flag} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{POLLIN} & È possibile la lettura.\\
+ \const{POLLRDNORM}& Sono disponibili in lettura dati normali.\\
+ \const{POLLRDBAND}& Sono disponibili in lettura dati prioritari.\\
+ \const{POLLPRI} & È possibile la lettura di \itindex{out-of-band} dati
+ urgenti.\\
+ \hline
+ \const{POLLOUT} & È possibile la scrittura immediata.\\
+ \const{POLLWRNORM}& È possibile la scrittura di dati normali.\\
+ \const{POLLWRBAND}& È possibile la scrittura di dati prioritari.\\
+ \hline
+ \const{POLLERR} & C'è una condizione di errore.\\
+ \const{POLLHUP} & Si è verificato un hung-up.\\
+ \const{POLLRDHUP} & Si è avuta una \textsl{half-close} su un
+ socket.\footnotemark\\
+ \const{POLLNVAL} & Il file descriptor non è aperto.\\
+ \hline
+ \const{POLLMSG} & Definito per compatibilità con SysV.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti per l'identificazione dei vari bit dei campi
+ \var{events} e \var{revents} di \struct{pollfd}.}
+ \label{tab:file_pollfd_flags}
+\end{table}
+
+\footnotetext{si tratta di una estensione specifica di Linux, disponibile a
+ partire dal kernel 2.6.17 definendo la marco \macro{\_GNU\_SOURCE}, che
+ consente di riconoscere la chiusura in scrittura dell'altro capo di un
+ socket, situazione che si viene chiamata appunto \itindex{half-close}
+ \textit{half-close} (\textsl{mezza chiusura}) su cui torneremo con maggiori
+ dettagli in sez.~\ref{sec:TCP_shutdown}.}
+
+Il valore \const{POLLMSG} non viene utilizzato ed è definito solo per
+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.
+
+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
+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. 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
+che tutte le volte che si vuole ripetere l'operazione occorre reinizializzarlo
+da capo. Questa operazione, che può essere molto onerosa se i file descriptor
+da tenere sotto osservazione sono molti, non è invece necessaria con
+\func{poll}.
+
+Abbiamo visto in sez.~\ref{sec:file_select} come lo standard POSIX preveda una
+variante di \func{select} che consente di gestire correttamente la ricezione
+dei segnali nell'attesa su un file descriptor. Con l'introduzione di una
+implementazione reale di \func{pselect} nel kernel 2.6.16, è stata aggiunta
+anche una analoga funzione che svolga lo stesso ruolo per \func{poll}.
+
+In questo caso si tratta di una estensione che è specifica di Linux e non è
+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{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.
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+ \item[\errcode{EINVAL}] il valore di \param{nfds} eccede il limite
+ \const{RLIMIT\_NOFILE}.
+ \end{errlist}
+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
+\index{maschera~dei~segnali} maschera di segnali; questa sarà la maschera
+utilizzata per tutto il tempo che la funzione resterà in attesa, all'uscita
+viene ripristinata la maschera originale. L'uso di questa funzione è cioè
+equivalente, come illustrato nella pagina di manuale, all'esecuzione atomica
+del seguente codice:
+\includecodesnip{listati/ppoll_means.c}
+
+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
+\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}
+
+\itindbeg{epoll}
+
+Nonostante \func{poll} presenti alcuni vantaggi rispetto a \func{select},
+anche questa funzione non è molto efficiente quando deve essere utilizzata con
+un gran numero di file descriptor,\footnote{in casi del genere \func{select}
+ viene scartata a priori, perché può avvenire che il numero di file
+ descriptor ecceda le dimensioni massime di un \itindex{file~descriptor~set}
+ \textit{file descriptor set}.} in particolare nel caso in cui solo pochi di
+questi diventano attivi. Il problema in questo caso è che il tempo impiegato
+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 (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
+diventati attivi. In una situazione come questa l'uso delle funzioni classiche
+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 (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
+ triggered}.\footnote{la nomenclatura è stata introdotta da Jonathan Lemon in
+ un articolo su \texttt{kqueue} al BSDCON 2000, e deriva da quella usata
+ nell'elettronica digitale.} In questa modalità vengono notificati i file
+descriptor che sono \textsl{pronti} per l'operazione richiesta, e questo
+avviene indipendentemente dalle operazioni che possono essere state fatte su
+di essi a partire dalla precedente notifica. Per chiarire meglio il concetto
+ricorriamo ad un esempio: se su un file descriptor sono diventati disponibili
+in lettura 2000 byte ma dopo la notifica ne sono letti solo 1000 (ed è quindi
+possibile eseguire una ulteriore lettura dei restanti 1000), in modalità
+\textit{level triggered} questo sarà nuovamente notificato come
+\textsl{pronto}.
+
+La seconda modalità, è detta \textit{edge triggered}, e prevede che invece
+vengano notificati solo i file descriptor che hanno subito una transizione da
+\textsl{non pronti} a \textsl{pronti}. Questo significa che in modalità
+\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 dati disponibili, e che
+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 è 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:
+
+\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{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{funcproto}
+
+Entrambe le funzioni restituiscono un file descriptor, detto anche
+\textit{epoll descriptor}; si tratta di un file descriptor speciale (per cui
+\func{read} e \func{write} non sono supportate) che viene associato alla
+infrastruttura utilizzata dal kernel per gestire la notifica degli eventi, e
+che può a sua volta essere messo sotto osservazione con una chiamata a
+\func{select}, \func{poll} o \func{epoll\_ctl}; in tal caso risulterà pronto
+quando saranno disponibili eventi da notificare riguardo i file descriptor da
+lui osservati.\footnote{è anche possibile inviarlo ad un altro processo
+ attraverso un socket locale (vedi sez.~\ref{sec:sock_fd_passing}) ma
+ l'operazione non ha alcun senso dato che il nuovo processo non avrà a
+ disposizione le copie dei file descriptor messe sotto osservazione tramite
+ esso.} Una volta che se ne sia terminato l'uso si potranno rilasciare tutte
+le risorse allocate chiudendolo semplicemente 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 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}] 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}.
+ \item[\errcode{EINVAL}] il file descriptor \param{epfd} non è stato ottenuto
+ con \func{epoll\_create}, o \param{fd} è lo stesso \param{epfd} o
+ l'operazione richiesta con \param{op} non è supportata.
+ \item[\errcode{ENOENT}] l'operazione richiesta è \const{EPOLL\_CTL\_MOD} o
+ \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{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{funcproto}
+
+La funzione prende sempre come primo argomento un file descriptor di
+\textit{epoll}, \param{epfd}, che indica quale istanza di \textit{epoll} usare
+e deve pertanto essere stato ottenuto in precedenza con una chiamata a
+\func{epoll\_create} o \func{epoll\_create1}. L'argomento \param{fd} indica
+invece il file descriptor che si vuole tenere sotto controllo, quest'ultimo
+può essere un qualunque file descriptor utilizzabile con \func{poll}, ed anche
+un altro file descriptor di \textit{epoll}, ma non lo stesso \param{epfd}.
+
+Il comportamento della funzione viene controllato dal valore dall'argomento
+\param{op} che consente di specificare quale operazione deve essere eseguita.
+Le costanti che definiscono i valori utilizzabili per \param{op}
+sono riportate in tab.~\ref{tab:epoll_ctl_operation}, assieme al significato
+delle operazioni cui fanno riferimento.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{EPOLL\_CTL\_ADD}& Aggiunge un nuovo file descriptor da osservare
+ \param{fd} alla lista dei file descriptor
+ controllati tramite \param{epfd}, in
+ \param{event} devono essere specificate le
+ modalità di osservazione.\\
+ \const{EPOLL\_CTL\_MOD}& Modifica le modalità di osservazione del file
+ descriptor \param{fd} secondo il contenuto di
+ \param{event}.\\
+ \const{EPOLL\_CTL\_DEL}& Rimuove il file descriptor \param{fd} dalla lista
+ dei file controllati tramite \param{epfd}.\\
+ \hline
+ \end{tabular}
+ \caption{Valori dell'argomento \param{op} che consentono di scegliere quale
+ operazione di controllo effettuare con la funzione \func{epoll\_ctl}.}
+ \label{tab:epoll_ctl_operation}
+\end{table}
+
+% era stata aggiunta EPOLL_CTL_DISABLE in previsione del kernel 3.7, vedi
+% http://lwn.net/Articles/520012/ e http://lwn.net/Articles/520198/
+% ma non è mai stata inserita.
+
+Le modalità di utilizzo di \textit{epoll} prevedono che si definisca qual'è
+l'insieme dei file descriptor da tenere sotto controllo utilizzando una serie
+di chiamate a \const{EPOLL\_CTL\_ADD}.\footnote{un difetto dell'interfaccia è
+ che queste chiamate devono essere ripetute per ciascun file descriptor,
+ incorrendo in una perdita di prestazioni qualora il numero di file
+ descriptor sia molto grande; per questo è stato proposto di introdurre come
+ estensione una funzione \code{epoll\_ctlv} che consenta di effettuare con
+ una sola chiamata le impostazioni per un blocco di file descriptor.} L'uso
+di \const{EPOLL\_CTL\_MOD} consente in seguito di modificare le modalità di
+osservazione di un file descriptor che sia già stato aggiunto alla lista di
+osservazione. Qualora non si abbia più interesse nell'osservazione di un file
+descriptor lo si può rimuovere dalla lista associata a \param{epfd} con
+\const{EPOLL\_CTL\_DEL}.
+
+Anche se è possibile tenere sotto controllo lo stesso file descriptor in due
+istanze distinte di \textit{epoll} in genere questo è sconsigliato in quanto
+entrambe riceveranno le notifiche, e gestire correttamente le notifiche
+multiple richiede molta attenzione. Se invece si cerca di inserire due volte
+lo stesso file descriptor nella stessa istanza di \textit{epoll} la funzione
+fallirà con un errore di \errval{EEXIST}. Tuttavia è possibile inserire nella
+stessa istanza file descriptor duplicati (si ricordi quanto visto in
+sez.~\ref{sec:file_dup}), una tecnica che può essere usata per registrarli con
+un valore diverso per \param{events} e classificare così diversi tipi di
+eventi.
+
+Si tenga presente che quando si chiude un file descriptor questo, se era stato
+posto sotto osservazione da una istanza di \textit{epoll}, viene rimosso
+automaticamente solo nel caso esso sia l'unico riferimento al file aperto
+sottostante (più precisamente alla struttura \kstruct{file}, si ricordi
+fig.~\ref{fig:file_dup}) e non è necessario usare
+\const{EPOLL\_CTL\_DEL}. Questo non avviene qualora esso sia stato duplicato
+(perché la suddetta struttura non viene disallocata) e si potranno ricevere
+eventi ad esso relativi anche dopo che lo si è chiuso; per evitare
+l'inconveniente è necessario rimuoverlo esplicitamente con
+\const{EPOLL\_CTL\_DEL}.
+
+L'ultimo argomento, \param{event}, deve essere un puntatore ad una struttura
+di tipo \struct{epoll\_event}, ed ha significato solo con le operazioni
+\const{EPOLL\_CTL\_MOD} e \const{EPOLL\_CTL\_ADD}, per le quali serve ad
+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 \val{NULL} ma se si
+ vuole mantenere la compatibilità con le versioni precedenti occorre usare un
+ puntatore valido.}
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.90\textwidth}
+ \includestruct{listati/epoll_event.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{epoll\_event}, che consente di specificare
+ gli eventi associati ad un file descriptor controllato con
+ \textit{epoll}.}
+ \label{fig:epoll_event}
+\end{figure}
+
+La struttura \struct{epoll\_event} è l'analoga di \struct{pollfd} e come
+quest'ultima serve sia in ingresso (quando usata con \func{epoll\_ctl}) ad
+impostare quali eventi osservare, che in uscita (nei risultati ottenuti con
+\func{epoll\_wait}) per ricevere le notifiche degli eventi avvenuti. La sua
+definizione è riportata in fig.~\ref{fig:epoll_event}.
+
+Il primo campo, \var{events}, è una maschera binaria in cui ciascun bit
+corrisponde o ad un tipo di evento, o una modalità di notifica; detto campo
+deve essere specificato come OR aritmetico delle costanti riportate in
+tab.~\ref{tab:epoll_events}. Nella prima parte della tabella si sono indicate
+le costanti che permettono di indicare il tipo di evento, che sono le
+equivalenti delle analoghe di tab.~\ref{tab:file_pollfd_flags} per
+\func{poll}. Queste sono anche quelle riportate nella struttura
+\struct{epoll\_event} restituita da \func{epoll\_wait} per indicare il tipo di
+evento presentatosi, insieme a quelle della seconda parte della tabella, che
+vengono comunque riportate anche se non le si sono impostate con
+\func{epoll\_ctl}. La terza parte della tabella contiene le costanti che
+modificano le modalità di notifica.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{EPOLLIN} & Il file è pronto per le operazioni di lettura
+ (analogo di \const{POLLIN}).\\
+ \const{EPOLLOUT} & Il file è pronto per le operazioni di scrittura
+ (analogo di \const{POLLOUT}).\\
+ \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}).\footnotemark\\
+ \const{EPOLLPRI} & Ci sono \itindex{out-of-band} dati urgenti
+ disponibili in lettura (analogo di
+ \const{POLLPRI}); questa condizione viene comunque
+ riportata in uscita, e non è necessaria impostarla
+ in ingresso.\\
+ \hline
+ \const{EPOLLERR} & Si è verificata una condizione di errore
+ (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; questa
+ condizione viene comunque riportata in uscita, e non
+ è necessaria impostarla in ingresso.\\
+ \hline
+ \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 (questa modalità è disponibile
+ solo a partire dal kernel 2.6.2).\\
+ \const{EPOLLWAKEUP} & Attiva la prevenzione della sospensione del sistema
+ se il file descriptor che si è marcato con esso
+ diventa pronto (aggiunto a partire dal kernel 3.5),
+ può essere impostato solo dall'amministratore (o da
+ un processo con la capacità
+ \const{CAP\_BLOCK\_SUSPEND}).\\
+ \hline
+ \end{tabular}
+ \caption{Costanti che identificano i bit del campo \param{events} di
+ \struct{epoll\_event}.}
+ \label{tab:epoll_events}
+\end{table}
+
+\footnotetext{questa modalità è disponibile solo a partire dal kernel 2.6.17,
+ ed è utile per riconoscere la chiusura di una connessione dall'altro capo di
+ un socket quando si lavora in modalità \textit{edge triggered}.}
+
+Il secondo campo, \var{data}, è una \direct{union} che serve a identificare il
+file descriptor a cui si intende fare riferimento, ed in astratto può
+contenere un valore qualsiasi (specificabile in diverse forme) che ne permetta
+una indicazione univoca. Il modo più comune di usarlo 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.
+
+% TODO verificare se prima o poi epoll_ctlv verrà introdotta
+
+Le impostazioni di default prevedono che la notifica degli eventi richiesti
+sia effettuata in modalità \textit{level triggered}, a meno che sul file
+descriptor non si sia impostata la modalità \textit{edge triggered},
+registrandolo con \const{EPOLLET} attivo nel campo \var{events}.
+
+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 (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 (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 di sistema che consente di attendere
+l'occorrenza di uno di tali eventi è \funcd{epoll\_wait}, il cui prototipo è:
+
+\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.
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale prima
+ della scadenza di \param{timeout}.
+ \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{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
+specificato in millisecondi tramite l'argomento \param{timeout}. Gli eventi
+registrati vengono riportati in un vettore di strutture \struct{epoll\_event}
+(che deve essere stato allocato in precedenza) all'indirizzo indicato
+dall'argomento \param{events}, fino ad un numero massimo di eventi impostato
+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 (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
+campo \param{events} di ciascuna di esse saranno attivi i flag relativi agli
+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, 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
+\textit{edge triggered}) del singolo file descriptor. L'interfaccia assicura
+che se arrivano più eventi fra due chiamate successive ad \func{epoll\_wait}
+questi vengano combinati. Inoltre qualora su un file descriptor fossero
+presenti eventi non ancora notificati, e si effettuasse una modifica
+dell'osservazione con \const{EPOLL\_CTL\_MOD}, questi verrebbero riletti alla
+luce delle modifiche.
+
+Si tenga presente infine che con l'uso della modalità \textit{edge triggered}
+il ritorno di \func{epoll\_wait} avviene solo quando il file descriptor ha
+cambiato stato diventando pronto. Esso non sarà riportato nuovamente fino ad
+un altro cambiamento di stato, per cui occorre assicurarsi di aver
+completamente esaurito le operazioni su di esso. Questa condizione viene
+generalmente rilevata dall'occorrere di un errore di \errcode{EAGAIN} al
+ritorno di una \func{read} o una \func{write}, (è opportuno ricordare ancora
+una volta che l'uso dell'\textit{I/O multiplexing} richiede di operare sui
+file in modalità non bloccante) ma questa non è la sola modalità possibile, ad
+esempio la condizione può essere riconosciuta anche per il fatto che sono
+stati restituiti meno dati di quelli richiesti.
+
+Si tenga presente che in modalità \textit{edge triggered}, dovendo esaurire le
+attività di I/O dei file descriptor risultati pronti per poter essere
+rinotificati, la gestione elementare per cui li si trattano uno per uno in
+sequenza può portare ad un effetto denominato \textit{starvation}
+(``\textsl{carestia}''). Si rischia cioè di concentrare le operazioni sul
+primo file descriptor che dispone di molti dati, prolungandole per tempi molto
+lunghi con un ritardo che può risultare eccessivo nei confronti di quelle da
+eseguire sugli altri che verrebbero dopo. Per evitare questo tipo di
+problematiche viene consigliato di usare \func{epoll\_wait} per registrare un
+elenco dei file descriptor da gestire, e di trattarli a turno in maniera più
+equa.
+
+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. Valgono le osservazioni fatte in
+sez.~\ref{sec:file_select}, e per poterlo fare 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 di sistema 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{funcproto}{
+\fhead{sys/epoll.h}
+\fdecl{int epoll\_pwait(int epfd, struct epoll\_event * events, int maxevents,
+ int timeout, \\
+\phantom{int epoll\_pwait(}const sigset\_t *sigmask)}
+
+\fdesc{Attende che uno dei file descriptor osservati sia pronto, mascherando
+ i segnali.} }
+
+{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
+originale, sostituita durante l'esecuzione da quella impostata con
+l'argomento \param{sigmask}; in sostanza la chiamata a questa funzione è
+equivalente al seguente codice, eseguito però in maniera atomica:
+\includecodesnip{listati/epoll_pwait_means.c}
+
+Si tenga presente che come le precedenti funzioni di \textit{I/O multiplexing}
+anche le funzioni dell'interfaccia di \textit{epoll} vengono utilizzate
+prevalentemente con i server di rete, quando si devono tenere sotto
+osservazione un gran numero di socket; per questo motivo rimandiamo anche in
+questo caso la trattazione di un esempio concreto a quando avremo esaminato in
+dettaglio le caratteristiche dei socket; in particolare si potrà trovare un
+programma che utilizza questa interfaccia in sez.~\ref{sec:TCP_serv_epoll}.
+
+\itindend{epoll}
+
+
+\subsection{La notifica di eventi tramite file descriptor}
+\label{sec:sig_signalfd_eventfd}
+
+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'\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
+una funzione di gestione in maniera asincrona e totalmente scorrelata
+dall'ordinario flusso di esecuzione del processo, si è però dimostrata quasi
+subito assai problematica. Oltre ai limiti relativi ai limiti al cosa si può
+fare all'interno della funzione del gestore di segnali (quelli illustrati in
+sez.~\ref{sec:sig_signal_handler}), c'è il problema più generale consistente
+nel fatto che questa modalità di funzionamento cozza con altre interfacce di
+programmazione previste dal sistema in cui si opera in maniera
+\textsl{sincrona}, come quelle dell'\textit{I/O multiplexing} appena
+illustrate.
+
+In questo tipo di interfacce infatti ci si aspetta che il processo gestisca
+gli eventi a cui deve reagire in maniera sincrona generando le opportune
+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}. 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
+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'\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.
+
+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. 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
+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'\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 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
+ 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
+ \index{maschera~dei~segnali} maschera dei segnali, il cui valore viene
+ impostato automaticamente dalle \acr{glibc}.} il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/signalfd.h}
+\fdecl{int signalfd(int fd, const sigset\_t *mask, int flags)}
+
+\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{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} 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
+segnali. Per creare ex-novo uno di questi file descriptor è necessario passare
+$-1$ come valore per l'argomento \param{fd}, ogni altro valore positivo verrà
+invece interpretato come il numero del file descriptor (che deve esser stato
+precedentemente creato sempre con \func{signalfd}) di cui si vogliono
+modificare le caratteristiche. Nel primo caso la funzione ritornerà il valore
+del nuovo file descriptor e nel secondo caso il valore indicato
+con \param{fd}, in caso di errore invece verrà restituito $-1$.
+
+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 \index{maschera~dei~segnali} maschera di segnali creata con
+l'uso delle apposite macro già illustrate in sez.~\ref{sec:sig_sigset}. La
+maschera deve indicare su quali segnali si intende operare con
+\func{signalfd}; l'elenco può essere modificato con una successiva chiamata a
+\func{signalfd}. Dato che \signal{SIGKILL} e \signal{SIGSTOP} non possono
+essere intercettati (e non prevedono neanche la possibilità di un gestore) un
+loro inserimento nella maschera verrà ignorato senza generare errori.
+
+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} (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
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{SFD\_NONBLOCK}& imposta sul file descriptor il flag di
+ \const{O\_NONBLOCK} per renderlo non bloccante.\\
+ \const{SFD\_CLOEXEC}& imposta il flag di \const{O\_CLOEXEC} per la
+ chiusura automatica del file descriptor nella
+ esecuzione di \func{exec}.\\
+ \hline
+ \end{tabular}
+ \caption{Valori dell'argomento \param{flags} per la funzione \func{signalfd}
+ che consentono di impostare i flag del file descriptor.}
+ \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). 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. 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 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]{0.90\textwidth}
+ \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.
+
+\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}